Sixty years since Silent Spring: towards a balanced view of the organochlorine pesticide literature

In this Rmarkdown document we provide the following workflow:

  • Objective 0. To investigate current literature characteristics such as time trend

  • Objective 1 . To explore the various characteristics of the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

  • Objective 2. To investigate current methodological practices within meta-analysis investigating the impacts of organochlorine pesticides. We will investigate how they currently search for existing literature, which effect sizes are used, how they adjust for heterogeneity and how they account for risk of bias.

  • Objective 3 - To investigate current reporting practices in existing meta-analyses examining the impacts of organochlorine pesticides.

  • Objective 4 - To investigate the research outputs across different countries and continents and investigate the degree of cross-country collaboration.

Load packages and data

Load Packages

rm(list = ls())
pacman::p_load(tidyverse,
hrbrthemes, 
patchwork,
here,
stringr,
knitr,
formatR,
forcats,
ggplot2,
bibliometrix,
igraph,
stringi,
stringdist,
circlize,
ggalluvial)
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)

Load data

Manually extracted pilot data is stored in five separate .csv files representing different aspects of the data (extracted via structured predefined Google Forms - one per table).

Bibliographic data records are exported from Scopus (including cited references field) in .bib format and locally saved as scopus.bib.

sd <- read_csv(here("data","ocp_srm_study_details.csv"), skip = 0)
ocp <- read_csv(here("data", "ocp_srm_ocp_details.csv"), skip = 0)
sub <- read_csv(here("data", "ocp_srm_subject_details.csv"), skip =0)
im <- read_csv(here("data", "ocp_srm_impact_details.csv"), skip =0)
sp <- read_csv(here("data", "ocp_srm_species_details.csv"), skip =0)
bib_sco <- convert2df(here("data","bib_sco.bib"), dbsource = "scopus", format = "bibtex")
## 
## Converting your scopus collection into a bibliographic dataframe
## 
## Done!
## 
## 
## Generating affiliation field tag AU_UN from C1:  Done!

Objective 0. To investigate current literature characteristics such as time trend

Figure 1

Time trends of total number of meta-analysis each year per subject

# Join the study and subject datasets
sd_sub <- left_join(sd, sub, by = "study_id")

# Data Transformation
# Count the number of publications per year and calculate cumulative sum
sd1 <- sd %>%
  count(publication_year) %>%
  mutate(n_cumulative = cumsum(n))

# Create the annual count plot
fig1a <- sd_sub %>%
  mutate(subjects = strsplit(subject, ",\\s+")) %>%
  unnest(subjects) %>%
  count(publication_year, subjects) %>%
  group_by(subjects = reorder(subjects, n)) %>%
  ggplot(aes(x = as.factor(publication_year), y = n, fill = subjects)) +
  geom_bar(stat = "identity", position = "stack", alpha = 0.7) +
  scale_y_continuous("Annual Article Count", limits = c(0,15)) +
  theme_minimal() +
  labs(x = "Year", y = "Article Count") +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) +
  scale_fill_brewer(palette = "Dark2") +
  labs(fill = "Subject Category") +
  guides(fill = guide_legend(override.aes = list(size=3)))

# Create the cumulative count plot
fig1b <-  sd_sub %>%
  mutate(subjects = strsplit(subject, ",\\s+")) %>%
  unnest(subjects) %>%
  count(publication_year, subjects) %>%
  group_by(subjects = reorder(subjects, n)) %>%
  mutate(n_cumulative = cumsum(n)) %>%
  ggplot(aes(x = publication_year, y = n_cumulative, fill = subjects)) +
  geom_area(size = 1.2, alpha = 0.7) +
  scale_y_continuous("Cumulative Article Count", limits = c(0,115)) +
  scale_x_continuous(breaks = seq(min(sd_sub$publication_year), max(sd_sub$publication_year), by = 1)) +
  theme_minimal() +
  labs(x = "Year", y = "Cumulative Article Count") +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) +
  scale_fill_brewer(palette = "Dark2") +
  labs(fill = "Subject") +
  guides(fill = guide_legend(override.aes = list(size=3)))

# Combine the two plots
fig1 <- fig1a /  fig1b

fig1

# ggsave(here("figures", "fig1.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "fig1.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s1

Time trends of total number of meta-analysis each year

# Create the annual Count Plot
figs1a <- sd1 %>%
  ggplot(aes(x = publication_year, y = n)) +
  geom_col(fill = "#1b9e77", alpha = 0.7) +
  geom_text(aes(label = n), position = position_stack(vjust = 0.6), fontface = "bold", color = "white", size = 3, hjust = 0.4) +
  scale_x_continuous(breaks = seq(min(sd1$publication_year), max(sd1$publication_year), by = 1)) +
  scale_y_continuous("Annual Article Count", limits = c(0,15)) +
  labs(x = "Year") +
  theme_minimal() +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) 

# Create the cuumulative Count Plot
figs1b <- sd1 %>%
  ggplot(aes(x = publication_year, y = n_cumulative)) +
  geom_line(color = "#7570b3", size = 1, linetype = "solid") +
  geom_point(shape = 21, size = 3, fill = "#7570b3", stroke = 0) +
  geom_text(aes(label = n_cumulative), hjust = -0.2, vjust = 1, size = 3, color = "black") +
  scale_x_continuous(breaks = seq(min(sd1$publication_year), max(sd1$publication_year), by = 1)) +
  scale_y_continuous("Cumulative Article Count", limits = c(0,120)) +
  labs(x = "Year") +
  theme_minimal() +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dashed"),
        panel.grid.minor.y = element_blank(),
        axis.line.x = element_line(size = 1.2),
        axis.line.y = element_line(size = 1.2),
        axis.title.x = element_text(size = 14, face = "bold"),
        axis.title.y = element_text(size = 14, face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1, size = 10, color = "#666666"),
        axis.text.y = element_text(size = 10, color = "#666666"),
        plot.title = element_text(size = 20, face = "bold"),
        plot.subtitle = element_text(size = 14),
        plot.caption = element_text(size = 10, hjust = 0)) 

# Combine the two plots
figs1 <- figs1a / figs1b

figs1

Objective 1. To characterise the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

Figure x - Total count of each organochlorine used in meta-analysis

# Transform the data 
ocp_count <-
  ocp %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  count(ocp) %>% 
  filter(!is.na(ocp)) %>% # filter out NA 
 filter(ocp != "not reported") %>% 
  arrange(desc(n)) %>% 
  mutate(ocp = ifelse(n <= 3, "other", as.character(ocp))) %>%  ## I NEED TO LIST ALL THE OTHERS HERE WITH THEIR COUNTS
  group_by(ocp) %>% 
  summarise(n =sum(n))

ocp_pct <- ocp_count %>%
  mutate(proportion = n/sum(ocp_count$n),
         percentage = proportion*100)

# Create the count plot 
ocp_count %>%
  ggplot(aes(x = n, y = reorder(ocp, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8, alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(ocp, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = ocp_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = - 0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(ocp_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 10),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none")

Figure x - Total proportion of meta-analysis per subject

note: some meta-analysis may contribute to multiple sections if involve multiple subjects

# Calculate total count for each category
subject_count <- 
  sub %>% 
    separate_rows(subject, sep = ",\\s+") %>% 
    count(subject)

# Calculate proportion and percentage for each category
subject_pct <- subject_count %>%
  mutate(proportion = n/sum(subject_count$n),
         percentage = proportion*100)

# Create the count plot
subject_count %>%
  ggplot(aes(x = n, y = reorder(subject, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(subject, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = subject_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(subject_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 10),
        axis.text.x = element_text(size = 10),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none")

# Calculate total count for each category
impact_count <- 
  im %>% 
    separate_rows(impact, sep = ",\\s+") %>% 
    count(impact) %>% 
  filter(impact != "NA") %>%
  mutate(impact = ifelse(n<= 1, "other", as.character(impact))) %>% 
    group_by(impact) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
impact_pct <- impact_count %>%
  mutate(proportion = n/sum(impact_count$n),
         percentage = proportion*100)

# Generate a graph
impact_count %>%
  ggplot(aes(x = n, y = reorder(impact, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(impact, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = impact_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(impact_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

Alluvial plot of ocp, subjecty and impact

# Transform the data 
df <- im %>%
  left_join(ocp, by = "study_id") %>%
  left_join(sub, by = "study_id") %>%
  separate_rows(subject, sep = ",\\s+") %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  separate_rows(impact, sep = ",\\s+") %>%
  mutate(ocp_convert = case_when( # Rename isomers and metabolites to parent chemical (besides DDT, DDD and DDE which are just isomers)
    grepl("DDT", ocp, ignore.case = TRUE) ~ "DDT", 
    grepl("DDD", ocp, ignore.case = TRUE) ~ "DDD", 
    grepl("DDE", ocp, ignore.case = TRUE) ~ "DDE", 
    grepl("HCH|Hexachloro|BHC|Lindane", ocp, ignore.case = TRUE) ~ "Hexachlorohexane", 
    grepl("Chlordane", ocp, ignore.case = TRUE) ~ "Chlordane",  
    grepl("Endosulfan", ocp, ignore.case = TRUE) ~ "Endosulfan", 
    grepl("Nonachlor", ocp, ignore.case = TRUE) ~ "Nonachlore", 
    grepl("Heptachlor", ocp, ignore.case = TRUE) ~ "Heptachlor",
    grepl("TCDD", ocp, ignore.case = TRUE) ~ "TCDD", 
    grepl("Endrin", ocp, ignore.case = TRUE) ~ "Endrin",
    TRUE ~ ocp)) %>%
  filter(!grepl("not reported", ocp_convert, ignore.case = TRUE)) %>%
  group_by(ocp_convert, subject, impact) %>%
  summarise(freq = n(), .groups = 'drop') %>%
  group_by(ocp_convert) %>%
  filter(sum(freq) > 2) %>% # filtered for ocp's with more than two occurrences 
  group_by(impact) %>% 
  filter(sum(freq) > 3) %>% # filter for impacts with more than three occurrences 
  mutate(subject = factor(subject, levels = c("environment", "non-human animal", "human"), ordered = TRUE))


# Plot alluvial plot between ocp, subject and impact 
ggplot(data = df,
       aes(axis1 = ocp_convert, axis2 = subject, axis3 = impact, y = freq)) +
  scale_x_discrete(limits = c("Organochlorine Pesticide", "Subject", "Impact"), expand = c(.05, .10)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = subject)) +
  geom_stratum(width = 1/2, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal() +
  scale_fill_brewer(palette = "Dark2", name = "Subject Category")

# Join the organochlorine pesticide details with the impact details
ocp_im <- left_join(ocp, im , by = "study_id")

# Separate rows in "ocp_im"
ocp_im1 <- separate_rows(ocp_im, ocp , sep = ", ", convert = TRUE)

ocp_im1 <- separate_rows(ocp_im1, impact , sep = ", ", convert = TRUE)

# Group by "ocp" and "impact" and summarize count
ocp_im_summary <- ocp_im1 %>%
  mutate(ocp = str_trim(ocp),
         impact = str_trim(impact)) %>%
  group_by(ocp, impact) %>%
  summarise(count = n()) %>%
  ungroup()

# Filter for top 5 pesticides and top 5 impacts
top_pesticides <- ocp_im_summary %>%
  filter(ocp != "not reported") %>%
  group_by(ocp) %>%
  summarise(total_count = sum(count)) %>%
  top_n(5, total_count) %>%
  pull(ocp)

top_impacts <- ocp_im_summary %>%
  group_by(impact) %>%
  summarise(total_count = sum(count)) %>%
  top_n(10, total_count) %>%
  pull(impact)

ocp_im_summary_filtered <- ocp_im_summary %>%
  filter(ocp %in% top_pesticides, impact %in% top_impacts)

# Create a circle plot with impact on the x-axis and ocp on the y-axis
ggplot(ocp_im_summary_filtered, aes(x = impact, y = ocp, size = count, fill = count)) +
  geom_point(shape = 21, color = "black") +
  scale_fill_gradient(low = "#98FB98", high = "#006400") +
 # geom_text(aes(label = count), color = "black", size = 7) +
  labs(x = "Impact", y = "Organochlorine Pesticide", fill = "Count") +
  theme_minimal() +
  theme(
    panel.grid.major.y = element_blank(),
    axis.line.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10, hjust = 1),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    plot.title = element_blank(),
    legend.text = element_text(size = 10),
    legend.title = element_text(size = 12)
  ) +
  scale_size_continuous(range = c(5, 20))

Objective 2. To investigate current methodological practices within meta-analysis investigating the impacts of organochlorine pesticides. We will investigate how they currently search for existing literature, which effect sizes are used, how they adjust for heterogeneity and how they account for risk of bias.

Figure x - Total count of each database used to search the literature within each meta-analysis

# Calculate the total count for each category
database_count <- sd %>% 
  separate_rows(database_search, sep = ",\\s+") %>% 
  count(database_search) %>% 
  filter(database_search != "not reported") %>% 
  arrange(desc(n)) %>% 
  mutate(database_search = ifelse(n<= 2, "other", as.character(database_search))) %>% 
    group_by(database_search) %>%
  summarise(n = sum(n))


# Calculate proportion and percentage for each category
database_pct <- database_count %>%
  mutate(proportion = n / sum(database_count$n),
         percentage = proportion * 100)

# Create the count plot
database_count %>%
  ggplot(aes(x = n, y = reorder(database_search, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(database_search, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = database_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(database_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
database_alluvial <- sd %>% 
    separate_rows(database_search, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, database_search) %>% 
    count(database_search, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(database_search) %>% 
    filter(sum(freq) > 2)  # filtered for scientic databases  with more than two occurrences 

# Create the Alluvial plot
ggplot(database_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = database_search)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Database Search"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal() 

Figure x - Total count of each effect size measure used within each meta-analysis

# Calculate the total count for each category
effectsize_count <- sd %>% 
  separate_rows(effect_size, sep = ",\\s+") %>% 
  count(effect_size) %>%
  filter(effect_size != "NA") %>%
  mutate(effect_size = ifelse(n<= 2, "other", as.character(effect_size))) %>% 
    group_by(effect_size) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
effectsize_pct <- effectsize_count %>%
  mutate(proportion = n / sum(effectsize_count$n),
         percentage = proportion * 100)

# Create the count plot
effectsize_count %>%
  ggplot(aes(x = n, y = reorder(effect_size, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(effect_size, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = effectsize_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(effectsize_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
effectsize_alluvial <- sd %>% 
    separate_rows(effect_size, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(effect_size)) %>%
    group_by(Journal_Citation_Report_Category, effect_size) %>% 
    count(effect_size, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(effect_size) #  %>% 
  #   filter(sum(freq) > 2)  # filtered for scientific databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(effectsize_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = effect_size)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Effect Size"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each software used to analyse the data within each meta-analysis

# Calculate the total count for each category
software_count <- sd %>% 
  separate_rows(software_analysis, sep = ",\\s+") %>% 
  count(software_analysis) %>%
  filter(software_analysis != "NA") %>%
  mutate(software_analysis = ifelse(n<= 2, "other", as.character(software_analysis))) %>% 
    group_by(software_analysis) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
software_pct <- software_count %>%
  mutate(proportion = n / sum(software_count$n),
         percentage = proportion * 100)

# Create the count plot
software_count %>%
  ggplot(aes(x = n, y = reorder(software_analysis, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(software_analysis, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = software_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(software_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
software_analysis_alluvial <- sd %>% 
    separate_rows(software_analysis, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(software_analysis)) %>%
    group_by(Journal_Citation_Report_Category, software_analysis) %>% 
    count(software_analysis, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(software_analysis)


# Create the Alluvial plot
ggplot(software_analysis_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = software_analysis)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Software Analysis"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each heterogeneity test used within each meta-analysis

# Calculate the total count for each category
heterogeneity_count <- sd %>% 
  separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>% 
  count(heterogeneity_assessment_method) %>%
  filter(heterogeneity_assessment_method != "NA") %>%
#  mutate(heterogeneity_assessment_method = ifelse(n<= 1, "other", as.character(heterogeneity_assessment_method))) %>% 
    group_by(heterogeneity_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
heterogeneity_pct <- heterogeneity_count %>%
  mutate(proportion = n / sum(heterogeneity_count$n),
         percentage = proportion * 100)

# Create the count plot
heterogeneity_count %>%
  ggplot(aes(x = n, y = reorder(heterogeneity_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(heterogeneity_assessment_method, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = heterogeneity_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(heterogeneity_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
heterogeneity_alluvial <- sd %>% 
    separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(heterogeneity_assessment_method)) %>%
    group_by(Journal_Citation_Report_Category, heterogeneity_assessment_method) %>% 
    count(heterogeneity_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(heterogeneity_assessment_method)  

# Create the Alluvial plot
ggplot(heterogeneity_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = heterogeneity_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Heterogeneity Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure xx - Total count for each sensitivity analysis used in each meta-analysis

# Calculate the total count for each category
sensitivity_count <- sd %>% 
  separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>% 
  count(sensitivity_analysis_method) %>%
  filter(sensitivity_analysis_method != "NA") %>%
 # mutate(sensitivity_analysis_method = ifelse(n<= 1, "other", as.character(sensitivity_analysis_method))) %>% 
    group_by(sensitivity_analysis_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
sensitivity_pct <- sensitivity_count %>%
  mutate(proportion = n / sum(sensitivity_count$n),
         percentage = proportion * 100)

# Create the count plot
sensitivity_count %>%
  ggplot(aes(x = n, y = reorder(sensitivity_analysis_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(sensitivity_analysis_method, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = sensitivity_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(sensitivity_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
sensitivity_analysis_alluvial <- sd %>% 
    separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(sensitivity_analysis_method)) %>%
    group_by(Journal_Citation_Report_Category, sensitivity_analysis_method) %>% 
    count(sensitivity_analysis_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(sensitivity_analysis_method)

# Create the Alluvial plot
ggplot(sensitivity_analysis_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = sensitivity_analysis_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Sensitivity Analysis Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count of each type of between study bias investiagted in each meta-analysis

# Calculate the total count for each category
bias_type_count <- sd %>% 
  separate_rows(bias_assessment_type, sep = ",\\s+") %>% 
  count(bias_assessment_type) %>%
  filter(bias_assessment_type != "NA") %>%
  group_by(bias_assessment_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_type_pct <- bias_type_count %>%
  mutate(proportion = n / sum(bias_type_count$n),
         percentage = proportion * 100)

# Create the count plot
bias_type_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_type, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(bias_assessment_type, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = bias_type_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(bias_type_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_type, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(bias_assessment_type)) %>%
    group_by(Journal_Citation_Report_Category, bias_assessment_type) %>% 
    count(bias_assessment_type, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_type)

# Create the Alluvial plot
ggplot(bias_assessment_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = bias_assessment_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count for each statistical methodology to investigate within study bias used in each meta-analysis

# Calculate the total count for each category
bias_method_count <- sd %>% 
  separate_rows(bias_assessment_method, sep = ",\\s+") %>% 
  count(bias_assessment_method) %>%
  filter(bias_assessment_method != "NA") %>%
    group_by(bias_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_method_pct <- bias_method_count %>%
  mutate(proportion = n / sum(bias_method_count$n),
         percentage = proportion * 100)

# Create the count plot
# Create the count plot
bias_method_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(bias_assessment_method, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = bias_method_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(bias_method_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    filter(!is.na(bias_assessment_method)) %>%
    group_by(Journal_Citation_Report_Category, bias_assessment_method) %>% 
    count(bias_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_method)

# Create the Alluvial plot
ggplot(bias_assessment_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = bias_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

# Calculate the total count for each category
rob_method_count <- sd %>% 
  separate_rows(rob_assessment_method, sep = ",\\s+") %>% 
  count(rob_assessment_method) %>%
  filter(rob_assessment_method != "NA") %>%
  group_by(rob_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
rob_method_pct <- rob_method_count %>%
  mutate(proportion = n / sum(rob_method_count$n),
         percentage = proportion * 100)

# Create the count plot
# Create the count plot
rob_method_count %>%
  ggplot(aes(x = n, y = reorder(rob_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(rob_assessment_method, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = rob_method_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(rob_method_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
robmethod_alluvial <- sd %>% 
    separate_rows(rob_assessment_method, sep = ",\\s+") %>%
   # filter(!is.na(rob_assessment_method)) %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>%
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, rob_assessment_method) %>% 
    count(rob_assessment_method, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(rob_assessment_method) %>% 
    filter(sum(freq) > 2)  # filtered for scientic databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(robmethod_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = rob_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "ROB Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Figure x - Total count for each methodology used to visualise the results of the meta-analsis

# Calculate the total count for each category
visualization_count <- sd %>% 
  separate_rows(visualization_method, sep = ",\\s+") %>% 
  count(visualization_method) %>%
  filter(visualization_method != "NA") %>%
    group_by(visualization_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
visualization_pct <- visualization_count %>%
  mutate(proportion = n / sum(visualization_count$n),
         percentage = proportion * 100)

# Create the count plot
visualization_count %>%
  ggplot(aes(x = n, y = reorder(visualization_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(visualization_method, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = visualization_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(visualization_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

Figure x - Total count for each reporting guideline followed in each meta-analysis

# Calculate the total count for each category
reporting_guide_count <- sd %>% 
  separate_rows(reporting_standards_type, sep = ",\\s+") %>% 
  count(reporting_standards_type) %>%
  filter(reporting_standards_type != "NA") %>%
    group_by(reporting_standards_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
reporting_guide_pct <- reporting_guide_count %>%
  mutate(proportion = n / sum(reporting_guide_count$n),
         percentage = proportion * 100)

# Create the count plot
# Create the count plot
reporting_guide_count %>%
  ggplot(aes(x = n, y = reorder(reporting_standards_type, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(reporting_standards_type, n)), hjust = 0.5, size = 4, color = "black") +
  geom_text(data = reporting_guide_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 3, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(reporting_guide_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )

# Data Transformation 
reporting_standards_alluvial <- sd %>% 
    separate_rows(reporting_standards_type, sep = ",\\s+") %>%
    separate_rows(Journal_Citation_Report_Category, sep = "/\\s+") %>%
    filter(!grepl("no category found", Journal_Citation_Report_Category, ignore.case = TRUE)) %>% 
    group_by(Journal_Citation_Report_Category, reporting_standards_type) %>% 
    count(reporting_standards_type, Journal_Citation_Report_Category) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(reporting_standards_type) %>% 
    filter(sum(freq) > 2)  # filtered for scientific databases  with more than two occurrences 


# Create the Alluvial plot
ggplot(reporting_standards_alluvial, aes(y = freq ,axis1 = Journal_Citation_Report_Category, axis2 = reporting_standards_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Reporting Standards Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Citation_Report_Category)) +
  geom_stratum(width = 1/8, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 3) +
  theme_minimal()

Objective 3 - To investigate current reporting practices in existing meta-analyses examining the impacts of organochlorine pesticides.

Summary plot for CEESAT data

CEESAT results are presented as a percentage of result per question

# Start the data manipulation
percent_ceesat_score <- sd %>%
  filter(!is.na(author_year)) %>%
  select(studies = author_year, starts_with("CEE")) %>%
  na.omit() %>%
  pivot_longer(cols = -studies, names_to = "question", values_to = "score") %>%
  group_by(question, score) %>%
  summarise(n = n(), .groups = 'drop') %>%
  mutate(percent = (n/sum(n))*100) %>%
  mutate(across(c(question, score), as.factor)) %>%
  mutate(question = factor(question, levels = rev(levels(question)))) %>%
  mutate(score = factor(score, levels = levels(score)[c(4,1,3,2)]))


# Plot of CEESAT scores
ggplot(data = percent_ceesat_score, aes(x = question, y = percent, fill = score)) +
  geom_col(width = 0.7, position = "fill", color = "black") +
  coord_flip(ylim = c(0, 1)) +
  guides(fill = guide_legend(reverse = TRUE)) +
  scale_fill_manual(values = c("#FF0000","#FFD700","#008000", "#DAA520"), name = "Score:") +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        panel.background = element_blank()) + 
  ylab("Proportion") + 
  xlab("CEESAT Question")

  • Objective 4. Bibliometrics: How is synthesized organochlorine pesticide evidence connected? We will investigate the countries and institutions that are primarily engaged in secondary research on organochlorine pesticides, and analyze the networks that exist between them. By doing so, we hope to gain insights into the collaborative relationships between different institutions and identify any patterns or trends in the distribution of research efforts.
fig5a <- biblioAnalysis(bib_sco)
plot(fig5a)

fig5c - thematic map based on keywords

par(mfrow=c(1,1), mar=c(0,2,0,2))
fig5c <- thematicMap(bib_sco, field = "ID", n = 1000, minfreq = 5, stemming = FALSE, size = 0.5, n.labels = 1, repel = TRUE)
plot(fig5c$map)

fig 5d - author collaboration network

NetMatrix_authors <- biblioNetwork(bib_sco, analysis = "collaboration",  network = "authors", sep = ";")
fig5d <- networkPlot(NetMatrix_authors,  n = 100, 
                                      Title = "Author collaboration", 
                                      type = "auto", size = 4, size.cex = TRUE, 
                                      edgesize = 10, labelsize = 1.1)

fig5e - country publications map

bibmap <- metaTagExtraction(bib_sco, Field = "AU1_CO", sep = ";") 
bibmap <- metaTagExtraction(bibmap, Field = "AU_CO", sep = ";") 
firstcountrycounts <- bibmap %>% 
  group_by(AU1_CO) %>%
  count() %>% 
  filter(!is.na(AU1_CO))  
world_map <- map_data("world") %>% 
  filter(! long > 180) 
firstcountrycounts$region <- str_to_title(firstcountrycounts$AU1_CO)
firstcountrycounts$region[firstcountrycounts$region == "Usa"] <- "USA" 
firstcountrycounts$region[firstcountrycounts$region == "United Kingdom"] <- "UK" 
emptymap <- tibble(region = unique(world_map$region), n = rep(0,length(unique(world_map$region)))) 
fullmap <- left_join(emptymap, firstcountrycounts, by = "region") 
fullmap$n <- fullmap$n.x + fullmap$n.y 
fullmap$n[is.na(fullmap$n)] <- 0 



fig5e <- fullmap %>% 
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map, color = "gray50") +
  expand_limits(x = world_map$long, y = world_map$lat) +
  coord_map("moll") +
  theme_minimal() +
  theme(legend.position="right") +
  scale_fill_gradient(low = "#98FB98", high = "#006400",
                    name = "Score", na.value = "gray70",
                    limits = c(1, 20),
      guide = guide_colorbar(direction = "vertical.")) +
  guides(fill = guide_colourbar(barwidth = unit(10, units = "mm"), barheight = unit(20, units = "mm")))
fig5e

Map of europe

fig5f <- fullmap %>% 
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map, color = "grey50") +
  coord_map("moll", ylim = c(30, 75), xlim = c(-25, 45)) + # set limits for Europe
  theme(legend.position = "right") +
  scale_fill_gradient(low = "#98FB98", high = "#006400",
                      name = "Score", na.value = "gray70",
                      limits = c(1, 10),
                      guide = guide_colorbar(direction = "vertical.")) +
  guides(fill = guide_colourbar(barwidth = unit(10, units = "mm"), barheight = unit(20, units = "mm")))

fig5f

fig5f - country collaboration network circle plot

# Extract countries from the affiliations
bib_sco2 <- metaTagExtraction(bib_sco, Field = "AU_CO", sep = ";")

# Create a network matrix of collaborations between countries
NetMatrix_country <- biblioNetwork(bib_sco2, analysis = "collaboration", network = "countries", sep = ";")

# Convert the network matrix to a standard matrix
NetMatrix_country <- as.matrix(NetMatrix_country)

# Remove the lower triangle (as this is duplication of info)
NetMatrix_country[lower.tri(NetMatrix_country)] <- 0 

# Change column and row names to title case
colnames(NetMatrix_country) <- str_to_title(colnames(NetMatrix_country))
rownames(NetMatrix_country) <- str_to_title(rownames(NetMatrix_country))

# Change "Usa" to "USA"
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "Usa"] <- "USA"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "Usa"] <- "USA"

# Change "United Kingdom" to "UK" for easier plotting
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "United Kingdom"] <- "UK"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "United Kingdom"] <- "UK"

# Define colors for each country
my.cols2 <- c(
  USA = "#377eb8",
  Spain = "#ffff33",
  China = "#e41a1c",
  France = "#999999",
  Canada = "#a6cee3",
  Denmark = "#b2df8a",
  Netherlands = "#377eb8",
  Belgium = "#984ea3",
  UK = "#ffff33",
  Australia = "#4daf4a",
  Brazil = "#4daf4a",
  Germany = "#b2df8a",
  Greece = "#f781bf",
  Korea = "#f781bf",
  Ireland = "#a65628",
  Norway = "#ff7f00",
  Sweden = "#4daf4a",
  Egypt = "#f781bf",
  Italy = "#e41a1c",
  Japan = "#1f78b4",
  Switzerland = "#984ea3",
  Turkey = "#33a02c",
  Austria = "#b2df8a",
  Israel = "#f781bf",
  NewZealand = "#4daf4a",
  Russia = "#999999",
  Singapore = "#b2df8a",
  Portugal = "#984ea3",
  Finland = "#b2df8a",
  Mexico = "#a65628",
  Poland = "#b2df8a",
  SouthAfrica = "#f781bf",
  Argentina = "#ff7f00",
  Chile = "#ff7f00",
  CzechRepublic = "#b2df8a",
  Iceland = "#b2df8a",
  Peru = "#ff7f00",
  Romania = "#fb9a99",
  Serbia = "#fb9a99",
  UAE = "#a65628"
)


# Create a chord diagram of the network matrix
fig5f <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.5, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

fig5g collaboration matrix with self citation removed

diag(NetMatrix_country) <- 0

# Create a chord diagram of the network matrix
fig5g <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1, grid.col = my.cols2)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + .1, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

fig 5h contitnent collaboration

NetMatrix_continent <- NetMatrix_country
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "USA"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "USA"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Spain"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Spain"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "China"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "China"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "France"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "France"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Canada"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Canada"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Denmark"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Denmark"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Netherlands"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Netherlands"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Belgium"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Belgium"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "UK"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "UK"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Australia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Australia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Brazil"] <- "South America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Brazil"] <- "South America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Germany"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Germany"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Finland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Finland"] <- "Europe"


colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Greece"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Greece"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Korea"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Korea"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Norway"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Norway"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Sweden"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Sweden"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Egypt"] <- "Africa"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Egypt"] <- "Africa"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Italy"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Italy"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Japan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Japan"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Portugal"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Portugal"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Switzerland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Switzerland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Turkey"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Turkey"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "India"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "India"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iran"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iran"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Costa Rica"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Costa Rica"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Czech Republic"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Czech Republic"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Hong Kong"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Hong Kong"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iceland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iceland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ireland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ireland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Mexico"] <- "North America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Mexico"] <- "North America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Romania"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Romania"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Slovakia"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Slovakia"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ukraine"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ukraine"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Oceania"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Oceania"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"


# collapsing
merge_matrix <- t(rowsum(t(NetMatrix_continent), group = colnames(NetMatrix_continent), na.rm = T))
merge_matrix2 <- rowsum(merge_matrix, group = rownames(merge_matrix))
# remove diagonal elements
diag(merge_matrix2) <- 0
# chord plot
chordDiagramFromMatrix(merge_matrix2)

# Define colors for each continent
my.cols2 <- c(
  Africa = "#CC79A7",
  NorthAmerica = "#F0E442",
  Asia = "#0072B2",
  Europe = "#E69F00",
  Oceania = "#009E73",
  SouthAmerica = "#D55E00"
)


# Create a chord diagram of the network matrix
fig5h <- chordDiagram(merge_matrix2, annotationTrack = "grid", preAllocateTracks = 1)
# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

CR <- citations(bib_sco, field = "article", sep = ";") #list of most cited articles
 cbind(CR$Cited[1:10]) #ten most cited articles
##                                                                                                                                                                         [,1]
## DERSIMONIAN, R., LAIRD, N., META-ANALYSIS IN CLINICAL TRIALS (1986) CONTROL CLIN TRIALS, 7, PP. 177-188                                                                    6
## HIGGINS, J.P., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327, PP. 557-560                                            6
## BEGG, C.B., MAZUMDAR, M., OPERATING CHARACTERISTICS OF A RANK CORRELATION TEST FOR PUBLICATION BIAS (1994) BIOMETRICS, 50, PP. 1088-1101                                   5
## HIGGINS, J.P.T., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327 (7414), PP. 557-560                                   5
## EGGER, M., DAVEY SMITH, G., SCHNEIDER, M., MINDER, C., BIAS IN META-ANALYSIS DETECTED BY A SIMPLE, GRAPHICAL TEST (1997) BMJ, 315 (7109), PP. 629-634                      4
## EGGER, M., DAVEY, S.G., SCHNEIDER, M., MINDER, C., BIAS IN META-ANALYSIS DETECTED BY A SIMPLE, GRAPHICAL TEST (1997) BMJ, 315 (7109), PP. 629-634                          4
## GREENLAND, S., QUANTITATIVE METHODS IN THE REVIEW OF EPIDEMIOLOGIC LITERATURE (1987) EPIDEMIOL REV, 9, PP. 1-30                                                            4
## HIGGINS, J.P., THOMPSON, S.G., DEEKS, J.J., ALTMAN, D.G., MEASURING INCONSISTENCY IN META-ANALYSES (2003) BMJ, 327 (7414), PP. 557-560                                     4
## PRIYADARSHI, A., KHUDER, S.A., SCHAUB, E.A., SHRIVASTAVA, S., A META-ANALYSIS OF PARKINSON'S DISEASE AND EXPOSURE TO PESTICIDES (2000) NEUROTOXICOLOGY, 21, PP. 435-440    4
## VAN MAELE-FABRY, G., WILLEMS, J.L., OCCUPATION RELATED PESTICIDE EXPOSURE AND CANCER OF THE PROSTATE: A META-ANALYSIS (2003) OCCUP ENVIRON MED, 60, PP. 634-642            4
CR <- citations(bib_sco, field = "author", sep = ";")
cbind(CR$Cited[1:10]) #ten most cited authors
##                [,1]
## BLAIR A         118
## LEE D H          69
## HOPPIN J A       61
## THOMPSON S G     52
## ZAHM S H         51
## ALTMAN D G       43
## NEEDHAM L L      41
## EGGER M          40
## GRANDJEAN P      39
## LONGNECKER M P   39
NetMatrix_coupling <- biblioNetwork(bib_sco, analysis = "coupling", network = "references", sep = "; ")
NetMatrix_coupling_plot <- networkPlot(NetMatrix_coupling, n = 20, 
                                       Title = "Paper co-citation", type = "fruchterman", size=T, 
                                       remove.multiple=FALSE, labelsize=0.8,edgesize = 5)

LS0tDQp0aXRsZTogIlNpeHR5IHllYXJzIHNpbmNlIFNpbGVudCBTcHJpbmc6IHRvd2FyZHMgYSBiYWxhbmNlZCB2aWV3IG9mIHRoZSBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGUgbGl0ZXJhdHVyZSAiDQphdXRob3I6ICJLeWxlIE1vcnJpc29uLCBDb3JhbGllIFdpbGxpYW1zLCBMb3JlbnpvIFJpY29sZmksIE1hbGdvcmF6YXRhIExhZ2lzeiwgU2hpbmljaGkgTmFrYWdhd2EiIA0KZGF0ZTogIjIwMjMtMDMtMDkiDQpvdXRwdXQ6IA0KICBybWRmb3JtYXRzOjpyb2JvYm9vazoNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdG9jX2RlcHRoOiA0DQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCmBgYHtyLCBpbmNsdWRlID0gRkFMU0V9DQpybShsaXN0ID0gbHMoKSkNCiMga25pdHIgc2V0dGluZw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBtZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwgDQogIGNhY2hlID0gVFJVRSwNCiAgZWNobz1UUlVFDQopDQpgYGANCg0KDQoNCg0KSW4gdGhpcyBSbWFya2Rvd24gZG9jdW1lbnQgd2UgcHJvdmlkZSB0aGUgZm9sbG93aW5nIHdvcmtmbG93OiAgIA0KDQotIE9iamVjdGl2ZSAwLiBUbyBpbnZlc3RpZ2F0ZSBjdXJyZW50IGxpdGVyYXR1cmUgY2hhcmFjdGVyaXN0aWNzIHN1Y2ggYXMgdGltZSB0cmVuZA0KDQotIE9iamVjdGl2ZSAxIC4gVG8gZXhwbG9yZSB0aGUgdmFyaW91cyBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMgbGl0ZXJhdHVyZSBzdWNoIGFzIHRoZSBwZXN0aWNpZGVzIHVzZWQsIHRoZSBpbXBhY3RzIGVsaWNpdGVkIGluIHJlc3BvbnNlIGFuZCB0aGUgc3ViamVjdHMgdGhhdCB3ZXJlIGludmVzdGlnYXRlZC4gDQoNCi0gT2JqZWN0aXZlIDIuIFRvIGludmVzdGlnYXRlIGN1cnJlbnQgbWV0aG9kb2xvZ2ljYWwgcHJhY3RpY2VzIHdpdGhpbiBtZXRhLWFuYWx5c2lzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gV2Ugd2lsbCBpbnZlc3RpZ2F0ZSBob3cgdGhleSBjdXJyZW50bHkgc2VhcmNoIGZvciBleGlzdGluZyBsaXRlcmF0dXJlLCB3aGljaCBlZmZlY3Qgc2l6ZXMgYXJlIHVzZWQsIGhvdyB0aGV5IGFkanVzdCBmb3IgaGV0ZXJvZ2VuZWl0eSBhbmQgaG93IHRoZXkgYWNjb3VudCBmb3IgcmlzayBvZiBiaWFzLiANCiANCiAtIE9iamVjdGl2ZSAzIC0gVG8gaW52ZXN0aWdhdGUgY3VycmVudCByZXBvcnRpbmcgcHJhY3RpY2VzIGluIGV4aXN0aW5nIG1ldGEtYW5hbHlzZXMgZXhhbWluaW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuDQogDQogLSBPYmplY3RpdmUgNCAtIFRvIGludmVzdGlnYXRlIHRoZSByZXNlYXJjaCBvdXRwdXRzIGFjcm9zcyBkaWZmZXJlbnQgY291bnRyaWVzIGFuZCBjb250aW5lbnRzIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgZGVncmVlIG9mIGNyb3NzLWNvdW50cnkgY29sbGFib3JhdGlvbi4NCiANCg0KIyAqKkxvYWQgcGFja2FnZXMgYW5kIGRhdGEqKg0KDQojIyBMb2FkIFBhY2thZ2VzIA0KDQpgYGB7ciwgcmVzdWx0cz0iaGlkZSJ9DQpybShsaXN0ID0gbHMoKSkNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwNCmhyYnJ0aGVtZXMsIA0KcGF0Y2h3b3JrLA0KaGVyZSwNCnN0cmluZ3IsDQprbml0ciwNCmZvcm1hdFIsDQpmb3JjYXRzLA0KZ2dwbG90MiwNCmJpYmxpb21ldHJpeCwNCmlncmFwaCwNCnN0cmluZ2ksDQpzdHJpbmdkaXN0LA0KY2lyY2xpemUsDQpnZ2FsbHV2aWFsKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkNCg0KYGBgDQoNCg0KIyMgTG9hZCBkYXRhDQoNCk1hbnVhbGx5IGV4dHJhY3RlZCBwaWxvdCBkYXRhIGlzIHN0b3JlZCBpbiBmaXZlIHNlcGFyYXRlICoqLmNzdioqIGZpbGVzIHJlcHJlc2VudGluZyBkaWZmZXJlbnQgYXNwZWN0cyBvZiB0aGUgZGF0YSAoZXh0cmFjdGVkIHZpYSBzdHJ1Y3R1cmVkIHByZWRlZmluZWQgR29vZ2xlIEZvcm1zIC0gb25lIHBlciB0YWJsZSkuIA0KDQpCaWJsaW9ncmFwaGljIGRhdGEgcmVjb3JkcyBhcmUgZXhwb3J0ZWQgZnJvbSBTY29wdXMgKGluY2x1ZGluZyBjaXRlZCByZWZlcmVuY2VzIGZpZWxkKSBpbiAuYmliIGZvcm1hdCBhbmQgbG9jYWxseSBzYXZlZCBhcyAqKnNjb3B1cy5iaWIqKi4gDQoNCg0KDQpgYGB7cn0NCnNkIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCJvY3Bfc3JtX3N0dWR5X2RldGFpbHMuY3N2IiksIHNraXAgPSAwKQ0Kb2NwIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9vY3BfZGV0YWlscy5jc3YiKSwgc2tpcCA9IDApDQpzdWIgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJvY3Bfc3JtX3N1YmplY3RfZGV0YWlscy5jc3YiKSwgc2tpcCA9MCkNCmltIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9pbXBhY3RfZGV0YWlscy5jc3YiKSwgc2tpcCA9MCkNCnNwIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9zcGVjaWVzX2RldGFpbHMuY3N2IiksIHNraXAgPTApDQpiaWJfc2NvIDwtIGNvbnZlcnQyZGYoaGVyZSgiZGF0YSIsImJpYl9zY28uYmliIiksIGRic291cmNlID0gInNjb3B1cyIsIGZvcm1hdCA9ICJiaWJ0ZXgiKQ0KYGBgDQoNCiMgT2JqZWN0aXZlIDAuIFRvIGludmVzdGlnYXRlIGN1cnJlbnQgbGl0ZXJhdHVyZSBjaGFyYWN0ZXJpc3RpY3Mgc3VjaCBhcyB0aW1lIHRyZW5kDQojIyBGaWd1cmUgMSANClRpbWUgdHJlbmRzIG9mIHRvdGFsIG51bWJlciBvZiBtZXRhLWFuYWx5c2lzIGVhY2ggeWVhciBwZXIgc3ViamVjdA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xNX0NCiMgSm9pbiB0aGUgc3R1ZHkgYW5kIHN1YmplY3QgZGF0YXNldHMNCnNkX3N1YiA8LSBsZWZ0X2pvaW4oc2QsIHN1YiwgYnkgPSAic3R1ZHlfaWQiKQ0KDQojIERhdGEgVHJhbnNmb3JtYXRpb24NCiMgQ291bnQgdGhlIG51bWJlciBvZiBwdWJsaWNhdGlvbnMgcGVyIHllYXIgYW5kIGNhbGN1bGF0ZSBjdW11bGF0aXZlIHN1bQ0Kc2QxIDwtIHNkICU+JQ0KICBjb3VudChwdWJsaWNhdGlvbl95ZWFyKSAlPiUNCiAgbXV0YXRlKG5fY3VtdWxhdGl2ZSA9IGN1bXN1bShuKSkNCg0KIyBDcmVhdGUgdGhlIGFubnVhbCBjb3VudCBwbG90DQpmaWcxYSA8LSBzZF9zdWIgJT4lDQogIG11dGF0ZShzdWJqZWN0cyA9IHN0cnNwbGl0KHN1YmplY3QsICIsXFxzKyIpKSAlPiUNCiAgdW5uZXN0KHN1YmplY3RzKSAlPiUNCiAgY291bnQocHVibGljYXRpb25feWVhciwgc3ViamVjdHMpICU+JQ0KICBncm91cF9ieShzdWJqZWN0cyA9IHJlb3JkZXIoc3ViamVjdHMsIG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gYXMuZmFjdG9yKHB1YmxpY2F0aW9uX3llYXIpLCB5ID0gbiwgZmlsbCA9IHN1YmplY3RzKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAic3RhY2siLCBhbHBoYSA9IDAuNykgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkFubnVhbCBBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLDE1KSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHggPSAiWWVhciIsIHkgPSAiQXJ0aWNsZSBDb3VudCIpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEuMiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICIjNjY2NjY2IiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBoanVzdCA9IDApKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSArDQogIGxhYnMoZmlsbCA9ICJTdWJqZWN0IENhdGVnb3J5IikgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MykpKQ0KDQojIENyZWF0ZSB0aGUgY3VtdWxhdGl2ZSBjb3VudCBwbG90DQpmaWcxYiA8LSAgc2Rfc3ViICU+JQ0KICBtdXRhdGUoc3ViamVjdHMgPSBzdHJzcGxpdChzdWJqZWN0LCAiLFxccysiKSkgJT4lDQogIHVubmVzdChzdWJqZWN0cykgJT4lDQogIGNvdW50KHB1YmxpY2F0aW9uX3llYXIsIHN1YmplY3RzKSAlPiUNCiAgZ3JvdXBfYnkoc3ViamVjdHMgPSByZW9yZGVyKHN1YmplY3RzLCBuKSkgJT4lDQogIG11dGF0ZShuX2N1bXVsYXRpdmUgPSBjdW1zdW0obikpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCB5ID0gbl9jdW11bGF0aXZlLCBmaWxsID0gc3ViamVjdHMpKSArDQogIGdlb21fYXJlYShzaXplID0gMS4yLCBhbHBoYSA9IDAuNykgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkN1bXVsYXRpdmUgQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwxMTUpKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKHNkX3N1YiRwdWJsaWNhdGlvbl95ZWFyKSwgbWF4KHNkX3N1YiRwdWJsaWNhdGlvbl95ZWFyKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHggPSAiWWVhciIsIHkgPSAiQ3VtdWxhdGl2ZSBBcnRpY2xlIENvdW50IikgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIGxpbmV0eXBlID0gImRhc2hlZCIpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAxLjIpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemUgPSAxMCwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMCkpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsNCiAgbGFicyhmaWxsID0gIlN1YmplY3QiKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0zKSkpDQoNCiMgQ29tYmluZSB0aGUgdHdvIHBsb3RzDQpmaWcxIDwtIGZpZzFhIC8gIGZpZzFiDQoNCmZpZzENCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWcxLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnMS5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHMxIA0KVGltZSB0cmVuZHMgb2YgdG90YWwgbnVtYmVyIG9mIG1ldGEtYW5hbHlzaXMgZWFjaCB5ZWFyDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDcmVhdGUgdGhlIGFubnVhbCBDb3VudCBQbG90DQpmaWdzMWEgPC0gc2QxICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMWI5ZTc3IiwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC42KSwgZm9udGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDMsIGhqdXN0ID0gMC40KSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgbWF4KHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgYnkgPSAxKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIkFubnVhbCBBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLDE1KSkgKw0KICBsYWJzKHggPSAiWWVhciIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEuMiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICIjNjY2NjY2IiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBoanVzdCA9IDApKSANCg0KIyBDcmVhdGUgdGhlIGN1dW11bGF0aXZlIENvdW50IFBsb3QNCmZpZ3MxYiA8LSBzZDEgJT4lDQogIGdncGxvdChhZXMoeCA9IHB1YmxpY2F0aW9uX3llYXIsIHkgPSBuX2N1bXVsYXRpdmUpKSArDQogIGdlb21fbGluZShjb2xvciA9ICIjNzU3MGIzIiwgc2l6ZSA9IDEsIGxpbmV0eXBlID0gInNvbGlkIikgKw0KICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSAzLCBmaWxsID0gIiM3NTcwYjMiLCBzdHJva2UgPSAwKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuX2N1bXVsYXRpdmUpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihzZDEkcHVibGljYXRpb25feWVhciksIG1heChzZDEkcHVibGljYXRpb25feWVhciksIGJ5ID0gMSkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJDdW11bGF0aXZlIEFydGljbGUgQ291bnQiLCBsaW1pdHMgPSBjKDAsMTIwKSkgKw0KICBsYWJzKHggPSAiWWVhciIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEuMiksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gMTAsIGNvbG9yID0gIiM2NjY2NjYiKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICIjNjY2NjY2IiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBoanVzdCA9IDApKSANCg0KIyBDb21iaW5lIHRoZSB0d28gcGxvdHMNCmZpZ3MxIDwtIGZpZ3MxYSAvIGZpZ3MxYg0KDQpmaWdzMQ0KDQoNCmBgYA0KDQoNCiMgT2JqZWN0aXZlIDEuIFRvIGNoYXJhY3RlcmlzZSB0aGUgb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcyBsaXRlcmF0dXJlIHN1Y2ggYXMgdGhlIHBlc3RpY2lkZXMgdXNlZCwgdGhlIGltcGFjdHMgZWxpY2l0ZWQgaW4gcmVzcG9uc2UgYW5kIHRoZSBzdWJqZWN0cyB0aGF0IHdlcmUgaW52ZXN0aWdhdGVkLiANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBvZiBlYWNoIG9yZ2Fub2NobG9yaW5lIHVzZWQgaW4gbWV0YS1hbmFseXNpcw0KDQpgYGB7cn0NCiMgVHJhbnNmb3JtIHRoZSBkYXRhIA0Kb2NwX2NvdW50IDwtDQogIG9jcCAlPiUgDQogIHNlcGFyYXRlX3Jvd3Mob2NwLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KG9jcCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG9jcCkpICU+JSAjIGZpbHRlciBvdXQgTkEgDQogZmlsdGVyKG9jcCAhPSAibm90IHJlcG9ydGVkIikgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpICU+JSANCiAgbXV0YXRlKG9jcCA9IGlmZWxzZShuIDw9IDMsICJvdGhlciIsIGFzLmNoYXJhY3RlcihvY3ApKSkgJT4lICAjIyBJIE5FRUQgVE8gTElTVCBBTEwgVEhFIE9USEVSUyBIRVJFIFdJVEggVEhFSVIgQ09VTlRTDQogIGdyb3VwX2J5KG9jcCkgJT4lIA0KICBzdW1tYXJpc2UobiA9c3VtKG4pKQ0KDQpvY3BfcGN0IDwtIG9jcF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShvY3BfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90IA0Kb2NwX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihvY3AsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKG9jcCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IG9jcF9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLSAwLjEsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KG9jcF9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIHByb3BvcnRpb24gb2YgbWV0YS1hbmFseXNpcyBwZXIgc3ViamVjdCANCm5vdGU6IHNvbWUgbWV0YS1hbmFseXNpcyBtYXkgY29udHJpYnV0ZSB0byBtdWx0aXBsZSBzZWN0aW9ucyBpZiBpbnZvbHZlIG11bHRpcGxlIHN1YmplY3RzIA0KYGBge3J9DQojIENhbGN1bGF0ZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0Kc3ViamVjdF9jb3VudCA8LSANCiAgc3ViICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKHN1YmplY3QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgICBjb3VudChzdWJqZWN0KQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpzdWJqZWN0X3BjdCA8LSBzdWJqZWN0X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKHN1YmplY3RfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpzdWJqZWN0X2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihzdWJqZWN0LCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIoc3ViamVjdCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHN1YmplY3RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KHN1YmplY3RfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmltcGFjdF9jb3VudCA8LSANCiAgaW0gJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoaW1wYWN0LCBzZXAgPSAiLFxccysiKSAlPiUgDQogICAgY291bnQoaW1wYWN0KSAlPiUgDQogIGZpbHRlcihpbXBhY3QgIT0gIk5BIikgJT4lDQogIG11dGF0ZShpbXBhY3QgPSBpZmVsc2Uobjw9IDEsICJvdGhlciIsIGFzLmNoYXJhY3RlcihpbXBhY3QpKSkgJT4lIA0KICAgIGdyb3VwX2J5KGltcGFjdCkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQppbXBhY3RfcGN0IDwtIGltcGFjdF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShpbXBhY3RfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgR2VuZXJhdGUgYSBncmFwaA0KaW1wYWN0X2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihpbXBhY3QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihpbXBhY3QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBpbXBhY3RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KGltcGFjdF9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCg0KYGBgDQoNCiMjIEFsbHV2aWFsIHBsb3Qgb2Ygb2NwLCBzdWJqZWN0eSBhbmQgaW1wYWN0IA0KYGBge3J9DQoNCiMgVHJhbnNmb3JtIHRoZSBkYXRhIA0KZGYgPC0gaW0gJT4lDQogIGxlZnRfam9pbihvY3AsIGJ5ID0gInN0dWR5X2lkIikgJT4lDQogIGxlZnRfam9pbihzdWIsIGJ5ID0gInN0dWR5X2lkIikgJT4lDQogIHNlcGFyYXRlX3Jvd3Moc3ViamVjdCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKG9jcCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGltcGFjdCwgc2VwID0gIixcXHMrIikgJT4lDQogIG11dGF0ZShvY3BfY29udmVydCA9IGNhc2Vfd2hlbiggIyBSZW5hbWUgaXNvbWVycyBhbmQgbWV0YWJvbGl0ZXMgdG8gcGFyZW50IGNoZW1pY2FsIChiZXNpZGVzIEREVCwgREREIGFuZCBEREUgd2hpY2ggYXJlIGp1c3QgaXNvbWVycykNCiAgICBncmVwbCgiRERUIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkREVCIsIA0KICAgIGdyZXBsKCJEREQiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiREREIiwgDQogICAgZ3JlcGwoIkRERSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJEREUiLCANCiAgICBncmVwbCgiSENIfEhleGFjaGxvcm98QkhDfExpbmRhbmUiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiSGV4YWNobG9yb2hleGFuZSIsIA0KICAgIGdyZXBsKCJDaGxvcmRhbmUiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiQ2hsb3JkYW5lIiwgIA0KICAgIGdyZXBsKCJFbmRvc3VsZmFuIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkVuZG9zdWxmYW4iLCANCiAgICBncmVwbCgiTm9uYWNobG9yIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIk5vbmFjaGxvcmUiLCANCiAgICBncmVwbCgiSGVwdGFjaGxvciIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJIZXB0YWNobG9yIiwNCiAgICBncmVwbCgiVENERCIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJUQ0REIiwgDQogICAgZ3JlcGwoIkVuZHJpbiIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJFbmRyaW4iLA0KICAgIFRSVUUgfiBvY3ApKSAlPiUNCiAgZmlsdGVyKCFncmVwbCgibm90IHJlcG9ydGVkIiwgb2NwX2NvbnZlcnQsIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JQ0KICBncm91cF9ieShvY3BfY29udmVydCwgc3ViamVjdCwgaW1wYWN0KSAlPiUNCiAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBncm91cF9ieShvY3BfY29udmVydCkgJT4lDQogIGZpbHRlcihzdW0oZnJlcSkgPiAyKSAlPiUgIyBmaWx0ZXJlZCBmb3Igb2NwJ3Mgd2l0aCBtb3JlIHRoYW4gdHdvIG9jY3VycmVuY2VzIA0KICBncm91cF9ieShpbXBhY3QpICU+JSANCiAgZmlsdGVyKHN1bShmcmVxKSA+IDMpICU+JSAjIGZpbHRlciBmb3IgaW1wYWN0cyB3aXRoIG1vcmUgdGhhbiB0aHJlZSBvY2N1cnJlbmNlcyANCiAgbXV0YXRlKHN1YmplY3QgPSBmYWN0b3Ioc3ViamVjdCwgbGV2ZWxzID0gYygiZW52aXJvbm1lbnQiLCAibm9uLWh1bWFuIGFuaW1hbCIsICJodW1hbiIpLCBvcmRlcmVkID0gVFJVRSkpDQoNCg0KIyBQbG90IGFsbHV2aWFsIHBsb3QgYmV0d2VlbiBvY3AsIHN1YmplY3QgYW5kIGltcGFjdCANCmdncGxvdChkYXRhID0gZGYsDQogICAgICAgYWVzKGF4aXMxID0gb2NwX2NvbnZlcnQsIGF4aXMyID0gc3ViamVjdCwgYXhpczMgPSBpbXBhY3QsIHkgPSBmcmVxKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk9yZ2Fub2NobG9yaW5lIFBlc3RpY2lkZSIsICJTdWJqZWN0IiwgIkltcGFjdCIpLCBleHBhbmQgPSBjKC4wNSwgLjEwKSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBzdWJqZWN0KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzIsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJTdWJqZWN0IENhdGVnb3J5IikNCmBgYA0KDQoNCmBgYHtyfQ0KDQojIEpvaW4gdGhlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZSBkZXRhaWxzIHdpdGggdGhlIGltcGFjdCBkZXRhaWxzDQpvY3BfaW0gPC0gbGVmdF9qb2luKG9jcCwgaW0gLCBieSA9ICJzdHVkeV9pZCIpDQoNCiMgU2VwYXJhdGUgcm93cyBpbiAib2NwX2ltIg0Kb2NwX2ltMSA8LSBzZXBhcmF0ZV9yb3dzKG9jcF9pbSwgb2NwICwgc2VwID0gIiwgIiwgY29udmVydCA9IFRSVUUpDQoNCm9jcF9pbTEgPC0gc2VwYXJhdGVfcm93cyhvY3BfaW0xLCBpbXBhY3QgLCBzZXAgPSAiLCAiLCBjb252ZXJ0ID0gVFJVRSkNCg0KIyBHcm91cCBieSAib2NwIiBhbmQgImltcGFjdCIgYW5kIHN1bW1hcml6ZSBjb3VudA0Kb2NwX2ltX3N1bW1hcnkgPC0gb2NwX2ltMSAlPiUNCiAgbXV0YXRlKG9jcCA9IHN0cl90cmltKG9jcCksDQogICAgICAgICBpbXBhY3QgPSBzdHJfdHJpbShpbXBhY3QpKSAlPiUNCiAgZ3JvdXBfYnkob2NwLCBpbXBhY3QpICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQ0KICB1bmdyb3VwKCkNCg0KIyBGaWx0ZXIgZm9yIHRvcCA1IHBlc3RpY2lkZXMgYW5kIHRvcCA1IGltcGFjdHMNCnRvcF9wZXN0aWNpZGVzIDwtIG9jcF9pbV9zdW1tYXJ5ICU+JQ0KICBmaWx0ZXIob2NwICE9ICJub3QgcmVwb3J0ZWQiKSAlPiUNCiAgZ3JvdXBfYnkob2NwKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX2NvdW50ID0gc3VtKGNvdW50KSkgJT4lDQogIHRvcF9uKDUsIHRvdGFsX2NvdW50KSAlPiUNCiAgcHVsbChvY3ApDQoNCnRvcF9pbXBhY3RzIDwtIG9jcF9pbV9zdW1tYXJ5ICU+JQ0KICBncm91cF9ieShpbXBhY3QpICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oY291bnQpKSAlPiUNCiAgdG9wX24oMTAsIHRvdGFsX2NvdW50KSAlPiUNCiAgcHVsbChpbXBhY3QpDQoNCm9jcF9pbV9zdW1tYXJ5X2ZpbHRlcmVkIDwtIG9jcF9pbV9zdW1tYXJ5ICU+JQ0KICBmaWx0ZXIob2NwICVpbiUgdG9wX3Blc3RpY2lkZXMsIGltcGFjdCAlaW4lIHRvcF9pbXBhY3RzKQ0KDQojIENyZWF0ZSBhIGNpcmNsZSBwbG90IHdpdGggaW1wYWN0IG9uIHRoZSB4LWF4aXMgYW5kIG9jcCBvbiB0aGUgeS1heGlzDQpnZ3Bsb3Qob2NwX2ltX3N1bW1hcnlfZmlsdGVyZWQsIGFlcyh4ID0gaW1wYWN0LCB5ID0gb2NwLCBzaXplID0gY291bnQsIGZpbGwgPSBjb3VudCkpICsNCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzk4RkI5OCIsIGhpZ2ggPSAiIzAwNjQwMCIpICsNCiAjIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb3VudCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDcpICsNCiAgbGFicyh4ID0gIkltcGFjdCIsIHkgPSAiT3JnYW5vY2hsb3JpbmUgUGVzdGljaWRlIiwgZmlsbCA9ICJDb3VudCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgaGp1c3QgPSAxKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikNCiAgKSArDQogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoNSwgMjApKQ0KDQpgYGANCg0KDQojIE9iamVjdGl2ZSAyLiBUbyBpbnZlc3RpZ2F0ZSBjdXJyZW50IG1ldGhvZG9sb2dpY2FsIHByYWN0aWNlcyB3aXRoaW4gbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIFdlIHdpbGwgaW52ZXN0aWdhdGUgaG93IHRoZXkgY3VycmVudGx5IHNlYXJjaCBmb3IgZXhpc3RpbmcgbGl0ZXJhdHVyZSwgd2hpY2ggZWZmZWN0IHNpemVzIGFyZSB1c2VkLCBob3cgdGhleSBhZGp1c3QgZm9yIGhldGVyb2dlbmVpdHkgYW5kIGhvdyB0aGV5IGFjY291bnQgZm9yIHJpc2sgb2YgYmlhcy4gDQoNCiMjIEZpZ3VyZSB4IC0gVG90YWwgY291bnQgb2YgZWFjaCBkYXRhYmFzZSB1c2VkIHRvIHNlYXJjaCB0aGUgbGl0ZXJhdHVyZSB3aXRoaW4gZWFjaCBtZXRhLWFuYWx5c2lzDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KZGF0YWJhc2VfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGRhdGFiYXNlX3NlYXJjaCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgZmlsdGVyKGRhdGFiYXNlX3NlYXJjaCAhPSAibm90IHJlcG9ydGVkIikgJT4lIA0KICBhcnJhbmdlKGRlc2MobikpICU+JSANCiAgbXV0YXRlKGRhdGFiYXNlX3NlYXJjaCA9IGlmZWxzZShuPD0gMiwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKGRhdGFiYXNlX3NlYXJjaCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoZGF0YWJhc2Vfc2VhcmNoKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZGF0YWJhc2VfcGN0IDwtIGRhdGFiYXNlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oZGF0YWJhc2VfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmRhdGFiYXNlX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihkYXRhYmFzZV9zZWFyY2gsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihkYXRhYmFzZV9zZWFyY2gsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBkYXRhYmFzZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgoZGF0YWJhc2VfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQoNCg0KYGBgDQoNCiANCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KZGF0YWJhc2VfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoZGF0YWJhc2Vfc2VhcmNoLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBjb3VudChkYXRhYmFzZV9zZWFyY2gsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBmaWx0ZXIoc3VtKGZyZXEpID4gMikgICMgZmlsdGVyZWQgZm9yIHNjaWVudGljIGRhdGFiYXNlcyAgd2l0aCBtb3JlIHRoYW4gdHdvIG9jY3VycmVuY2VzIA0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGRhdGFiYXNlX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gZGF0YWJhc2Vfc2VhcmNoKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkRhdGFiYXNlIFNlYXJjaCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpIA0KDQoNCg0KICANCmBgYA0KDQojIyBGaWd1cmUgeCAtIFRvdGFsIGNvdW50IG9mIGVhY2ggZWZmZWN0IHNpemUgbWVhc3VyZSB1c2VkIHdpdGhpbiBlYWNoIG1ldGEtYW5hbHlzaXMNCmBgYHtyIHBsb3QgZWZmZWN0IHNpemUgdXNlZCB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmVmZmVjdHNpemVfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGVmZmVjdF9zaXplLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGVmZmVjdF9zaXplKSAlPiUNCiAgZmlsdGVyKGVmZmVjdF9zaXplICE9ICJOQSIpICU+JQ0KICBtdXRhdGUoZWZmZWN0X3NpemUgPSBpZmVsc2Uobjw9IDIsICJvdGhlciIsIGFzLmNoYXJhY3RlcihlZmZlY3Rfc2l6ZSkpKSAlPiUgDQogICAgZ3JvdXBfYnkoZWZmZWN0X3NpemUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZWZmZWN0c2l6ZV9wY3QgPC0gZWZmZWN0c2l6ZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGVmZmVjdHNpemVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmVmZmVjdHNpemVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGVmZmVjdF9zaXplLCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIoZWZmZWN0X3NpemUsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBlZmZlY3RzaXplX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChlZmZlY3RzaXplX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KZWZmZWN0c2l6ZV9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhlZmZlY3Rfc2l6ZSwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKGVmZmVjdF9zaXplKSkgJT4lDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGVmZmVjdF9zaXplKSAlPiUgDQogICAgY291bnQoZWZmZWN0X3NpemUsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShlZmZlY3Rfc2l6ZSkgIyAgJT4lIA0KICAjICAgZmlsdGVyKHN1bShmcmVxKSA+IDIpICAjIGZpbHRlcmVkIGZvciBzY2llbnRpZmljIGRhdGFiYXNlcyAgd2l0aCBtb3JlIHRoYW4gdHdvIG9jY3VycmVuY2VzIA0KDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpnZ3Bsb3QoZWZmZWN0c2l6ZV9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IGVmZmVjdF9zaXplKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkVmZmVjdCBTaXplIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSB4IC0gVG90YWwgY291bnQgb2YgZWFjaCBzb2Z0d2FyZSB1c2VkIHRvIGFuYWx5c2UgdGhlIGRhdGEgd2l0aGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnNvZnR3YXJlX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhzb2Z0d2FyZV9hbmFseXNpcywgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChzb2Z0d2FyZV9hbmFseXNpcykgJT4lDQogIGZpbHRlcihzb2Z0d2FyZV9hbmFseXNpcyAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKHNvZnR3YXJlX2FuYWx5c2lzID0gaWZlbHNlKG48PSAyLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIoc29mdHdhcmVfYW5hbHlzaXMpKSkgJT4lIA0KICAgIGdyb3VwX2J5KHNvZnR3YXJlX2FuYWx5c2lzKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnNvZnR3YXJlX3BjdCA8LSBzb2Z0d2FyZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHNvZnR3YXJlX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpzb2Z0d2FyZV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoc29mdHdhcmVfYW5hbHlzaXMsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihzb2Z0d2FyZV9hbmFseXNpcywgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHNvZnR3YXJlX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChzb2Z0d2FyZV9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQoNCg0KDQpgYGANCg0KYGBge3J9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpzb2Z0d2FyZV9hbmFseXNpc19hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhzb2Z0d2FyZV9hbmFseXNpcywgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKHNvZnR3YXJlX2FuYWx5c2lzKSkgJT4lDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHNvZnR3YXJlX2FuYWx5c2lzKSAlPiUgDQogICAgY291bnQoc29mdHdhcmVfYW5hbHlzaXMsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShzb2Z0d2FyZV9hbmFseXNpcykNCg0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KHNvZnR3YXJlX2FuYWx5c2lzX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gc29mdHdhcmVfYW5hbHlzaXMpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiU29mdHdhcmUgQW5hbHlzaXMiKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpKSArDQogIGdlb21fc3RyYXR1bSh3aWR0aCA9IDEvOCwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIHNpemUgPSAzKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBvZiBlYWNoIGhldGVyb2dlbmVpdHkgdGVzdCB1c2VkIHdpdGhpbiBlYWNoIG1ldGEtYW5hbHlzaXMNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpoZXRlcm9nZW5laXR5X2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBmaWx0ZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiMgIG11dGF0ZShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kID0gaWZlbHNlKG48PSAxLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpoZXRlcm9nZW5laXR5X3BjdCA8LSBoZXRlcm9nZW5laXR5X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oaGV0ZXJvZ2VuZWl0eV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uICogMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KaGV0ZXJvZ2VuZWl0eV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBoZXRlcm9nZW5laXR5X3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChoZXRlcm9nZW5laXR5X2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KYGBgDQogDQogDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmhldGVyb2dlbmVpdHlfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkgJT4lIA0KICAgIGNvdW50KGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSAgDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpnZ3Bsb3QoaGV0ZXJvZ2VuZWl0eV9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiSGV0ZXJvZ2VuZWl0eSBBc3Nlc3NtZW50IE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KIA0KIyMgRmlndXJlIHh4IC0gVG90YWwgY291bnQgZm9yIGVhY2ggc2Vuc2l0aXZpdHkgYW5hbHlzaXMgdXNlZCBpbiBlYWNoIG1ldGEtYW5hbHlzaXMNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpzZW5zaXRpdml0eV9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3Moc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCkgJT4lDQogIGZpbHRlcihzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QgIT0gIk5BIikgJT4lDQogIyBtdXRhdGUoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kID0gaWZlbHNlKG48PSAxLCAib3RoZXIiLCBhcy5jaGFyYWN0ZXIoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSkpICU+JSANCiAgICBncm91cF9ieShzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0Kc2Vuc2l0aXZpdHlfcGN0IDwtIHNlbnNpdGl2aXR5X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oc2Vuc2l0aXZpdHlfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCnNlbnNpdGl2aXR5X2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBzZW5zaXRpdml0eV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgoc2Vuc2l0aXZpdHlfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCnNlbnNpdGl2aXR5X2FuYWx5c2lzX2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpICU+JSANCiAgICBjb3VudChzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpnZ3Bsb3Qoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfYWxsdXZpYWwsIGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYXhpczIgPSBzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiU2Vuc2l0aXZpdHkgQW5hbHlzaXMgTWV0aG9kIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSB4IC0gVG90YWwgY291bnQgb2YgZWFjaCB0eXBlIG9mIGJldHdlZW4gc3R1ZHkgYmlhcyBpbnZlc3RpYWd0ZWQgaW4gZWFjaCBtZXRhLWFuYWx5c2lzDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KYmlhc190eXBlX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfdHlwZSwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChiaWFzX2Fzc2Vzc21lbnRfdHlwZSkgJT4lDQogIGZpbHRlcihiaWFzX2Fzc2Vzc21lbnRfdHlwZSAhPSAiTkEiKSAlPiUNCiAgZ3JvdXBfYnkoYmlhc19hc3Nlc3NtZW50X3R5cGUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KYmlhc190eXBlX3BjdCA8LSBiaWFzX3R5cGVfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShiaWFzX3R5cGVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmJpYXNfdHlwZV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoYmlhc19hc3Nlc3NtZW50X3R5cGUsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihiaWFzX2Fzc2Vzc21lbnRfdHlwZSwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IGJpYXNfdHlwZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgoYmlhc190eXBlX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KDQpgYGANCg0KDQpgYGB7cn0NCg0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0KYmlhc19hc3Nlc3NtZW50X2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKGJpYXNfYXNzZXNzbWVudF90eXBlLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGZpbHRlcighaXMubmEoYmlhc19hc3Nlc3NtZW50X3R5cGUpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYmlhc19hc3Nlc3NtZW50X3R5cGUpICU+JSANCiAgICBjb3VudChiaWFzX2Fzc2Vzc21lbnRfdHlwZSwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF90eXBlKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGJpYXNfYXNzZXNzbWVudF9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IGJpYXNfYXNzZXNzbWVudF90eXBlKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkJpYXMgQXNzZXNzbWVudCBUeXBlIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzgsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gMykgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCBzdGF0aXN0aWNhbCBtZXRob2RvbG9neSB0byBpbnZlc3RpZ2F0ZSB3aXRoaW4gc3R1ZHkgYmlhcyB1c2VkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGJpYXNfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBmaWx0ZXIoYmlhc19hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX3BjdCA8LSBiaWFzX21ldGhvZF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGJpYXNfbWV0aG9kX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KYmlhc19tZXRob2RfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGJpYXNfYXNzZXNzbWVudF9tZXRob2QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNCwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gYmlhc19tZXRob2RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KGJpYXNfbWV0aG9kX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KDQpgYGANCg0KYGBge3J9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpiaWFzX2Fzc2Vzc21lbnRfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKGJpYXNfYXNzZXNzbWVudF9tZXRob2QpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgYmlhc19hc3Nlc3NtZW50X21ldGhvZCkgJT4lIA0KICAgIGNvdW50KGJpYXNfYXNzZXNzbWVudF9tZXRob2QsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KGJpYXNfYXNzZXNzbWVudF9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IGJpYXNfYXNzZXNzbWVudF9tZXRob2QpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiQmlhcyBBc3Nlc3NtZW50IE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0Kcm9iX21ldGhvZF9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3Mocm9iX2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KHJvYl9hc3Nlc3NtZW50X21ldGhvZCkgJT4lDQogIGZpbHRlcihyb2JfYXNzZXNzbWVudF9tZXRob2QgIT0gIk5BIikgJT4lDQogIGdyb3VwX2J5KHJvYl9hc3Nlc3NtZW50X21ldGhvZCkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpyb2JfbWV0aG9kX3BjdCA8LSByb2JfbWV0aG9kX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0ocm9iX21ldGhvZF9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uICogMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCnJvYl9tZXRob2RfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHJvYl9hc3Nlc3NtZW50X21ldGhvZCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKHJvYl9hc3Nlc3NtZW50X21ldGhvZCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHJvYl9tZXRob2RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAwKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KHJvYl9tZXRob2RfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCnJvYm1ldGhvZF9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhyb2JfYXNzZXNzbWVudF9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIyBmaWx0ZXIoIWlzLm5hKHJvYl9hc3Nlc3NtZW50X21ldGhvZCkpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIHNlcCA9ICIvXFxzKyIpICU+JQ0KICAgIGZpbHRlcighZ3JlcGwoIm5vIGNhdGVnb3J5IGZvdW5kIiwgSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGlnbm9yZS5jYXNlID0gVFJVRSkpICU+JSANCiAgICBncm91cF9ieShKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgcm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUgDQogICAgY291bnQocm9iX2Fzc2Vzc21lbnRfbWV0aG9kLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkocm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUgDQogICAgZmlsdGVyKHN1bShmcmVxKSA+IDIpICAjIGZpbHRlcmVkIGZvciBzY2llbnRpYyBkYXRhYmFzZXMgIHdpdGggbW9yZSB0aGFuIHR3byBvY2N1cnJlbmNlcyANCg0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZ2dwbG90KHJvYm1ldGhvZF9hbGx1dmlhbCwgYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCBheGlzMiA9IHJvYl9hc3Nlc3NtZW50X21ldGhvZCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJST0IgQXNzZXNzbWVudCBNZXRob2QiKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnkpKSArDQogIGdlb21fc3RyYXR1bSh3aWR0aCA9IDEvOCwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIHNpemUgPSAzKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCBtZXRob2RvbG9neSB1c2VkIHRvIHZpc3VhbGlzZSB0aGUgcmVzdWx0cyBvZiB0aGUgbWV0YS1hbmFsc2lzDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KdmlzdWFsaXphdGlvbl9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3ModmlzdWFsaXphdGlvbl9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQodmlzdWFsaXphdGlvbl9tZXRob2QpICU+JQ0KICBmaWx0ZXIodmlzdWFsaXphdGlvbl9tZXRob2QgIT0gIk5BIikgJT4lDQogICAgZ3JvdXBfYnkodmlzdWFsaXphdGlvbl9tZXRob2QpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KdmlzdWFsaXphdGlvbl9wY3QgPC0gdmlzdWFsaXphdGlvbl9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHZpc3VhbGl6YXRpb25fY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCnZpc3VhbGl6YXRpb25fY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHZpc3VhbGl6YXRpb25fbWV0aG9kLCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIodmlzdWFsaXphdGlvbl9tZXRob2QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA0LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSB2aXN1YWxpemF0aW9uX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gMywgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heCh2aXN1YWxpemF0aW9uX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KDQpgYGANCg0KIyMgRmlndXJlIHggLSBUb3RhbCBjb3VudCBmb3IgZWFjaCByZXBvcnRpbmcgZ3VpZGVsaW5lIGZvbGxvd2VkIGluIGVhY2ggbWV0YS1hbmFseXNpcw0KYGBge3J9DQoNCiMgQ2FsY3VsYXRlIHRoZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KcmVwb3J0aW5nX2d1aWRlX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSAlPiUNCiAgZmlsdGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSAhPSAiTkEiKSAlPiUNCiAgICBncm91cF9ieShyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KcmVwb3J0aW5nX2d1aWRlX3BjdCA8LSByZXBvcnRpbmdfZ3VpZGVfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShyZXBvcnRpbmdfZ3VpZGVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpyZXBvcnRpbmdfZ3VpZGVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHJlcG9ydGluZ19ndWlkZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDApLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgocmVwb3J0aW5nX2d1aWRlX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkNCg0KDQpgYGANCg0KYGBge3J9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpyZXBvcnRpbmdfc3RhbmRhcmRzX2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICBzZXBhcmF0ZV9yb3dzKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgc2VwID0gIi9cXHMrIikgJT4lDQogICAgZmlsdGVyKCFncmVwbCgibm8gY2F0ZWdvcnkgZm91bmQiLCBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lIA0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5LCByZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpICU+JSANCiAgICBjb3VudChyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUsIEpvdXJuYWxfQ2l0YXRpb25fUmVwb3J0X0NhdGVnb3J5KSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpICU+JSANCiAgICBmaWx0ZXIoc3VtKGZyZXEpID4gMikgICMgZmlsdGVyZWQgZm9yIHNjaWVudGlmaWMgZGF0YWJhc2VzICB3aXRoIG1vcmUgdGhhbiB0d28gb2NjdXJyZW5jZXMgDQoNCg0KIyBDcmVhdGUgdGhlIEFsbHV2aWFsIHBsb3QNCmdncGxvdChyZXBvcnRpbmdfc3RhbmRhcmRzX2FsbHV2aWFsLCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DaXRhdGlvbl9SZXBvcnRfQ2F0ZWdvcnksIGF4aXMyID0gcmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlJlcG9ydGluZyBTdGFuZGFyZHMgVHlwZSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NpdGF0aW9uX1JlcG9ydF9DYXRlZ29yeSkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS84LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDMpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIE9iamVjdGl2ZSAzIC0gVG8gaW52ZXN0aWdhdGUgY3VycmVudCByZXBvcnRpbmcgcHJhY3RpY2VzIGluIGV4aXN0aW5nIG1ldGEtYW5hbHlzZXMgZXhhbWluaW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuDQoNCiMjIFN1bW1hcnkgcGxvdCBmb3IgQ0VFU0FUIGRhdGENCg0KQ0VFU0FUIHJlc3VsdHMgYXJlIHByZXNlbnRlZCBhcyBhIHBlcmNlbnRhZ2Ugb2YgcmVzdWx0IHBlciBxdWVzdGlvbg0KDQpgYGB7ciBwbG90IENFRVNBVCBzdW1tYXJ5IH0NCg0KIyBTdGFydCB0aGUgZGF0YSBtYW5pcHVsYXRpb24NCnBlcmNlbnRfY2Vlc2F0X3Njb3JlIDwtIHNkICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGF1dGhvcl95ZWFyKSkgJT4lDQogIHNlbGVjdChzdHVkaWVzID0gYXV0aG9yX3llYXIsIHN0YXJ0c193aXRoKCJDRUUiKSkgJT4lDQogIG5hLm9taXQoKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtc3R1ZGllcywgbmFtZXNfdG8gPSAicXVlc3Rpb24iLCB2YWx1ZXNfdG8gPSAic2NvcmUiKSAlPiUNCiAgZ3JvdXBfYnkocXVlc3Rpb24sIHNjb3JlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBtdXRhdGUocGVyY2VudCA9IChuL3N1bShuKSkqMTAwKSAlPiUNCiAgbXV0YXRlKGFjcm9zcyhjKHF1ZXN0aW9uLCBzY29yZSksIGFzLmZhY3RvcikpICU+JQ0KICBtdXRhdGUocXVlc3Rpb24gPSBmYWN0b3IocXVlc3Rpb24sIGxldmVscyA9IHJldihsZXZlbHMocXVlc3Rpb24pKSkpICU+JQ0KICBtdXRhdGUoc2NvcmUgPSBmYWN0b3Ioc2NvcmUsIGxldmVscyA9IGxldmVscyhzY29yZSlbYyg0LDEsMywyKV0pKQ0KDQoNCiMgUGxvdCBvZiBDRUVTQVQgc2NvcmVzDQpnZ3Bsb3QoZGF0YSA9IHBlcmNlbnRfY2Vlc2F0X3Njb3JlLCBhZXMoeCA9IHF1ZXN0aW9uLCB5ID0gcGVyY2VudCwgZmlsbCA9IHNjb3JlKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDAuNywgcG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDEpKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkYwMDAwIiwiI0ZGRDcwMCIsIiMwMDgwMDAiLCAiI0RBQTUyMCIpLCBuYW1lID0gIlNjb3JlOiIpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSArIA0KICB5bGFiKCJQcm9wb3J0aW9uIikgKyANCiAgeGxhYigiQ0VFU0FUIFF1ZXN0aW9uIikNCmBgYA0KDQogLSAqKk9iamVjdGl2ZSA0LglCaWJsaW9tZXRyaWNzOiBIb3cgaXMgc3ludGhlc2l6ZWQgb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlIGV2aWRlbmNlIGNvbm5lY3RlZD8qKiBXZSB3aWxsIGludmVzdGlnYXRlIHRoZSBjb3VudHJpZXMgYW5kIGluc3RpdHV0aW9ucyB0aGF0IGFyZSBwcmltYXJpbHkgZW5nYWdlZCBpbiBzZWNvbmRhcnkgcmVzZWFyY2ggb24gb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcywgYW5kIGFuYWx5emUgdGhlIG5ldHdvcmtzIHRoYXQgZXhpc3QgYmV0d2VlbiB0aGVtLiBCeSBkb2luZyBzbywgd2UgaG9wZSB0byBnYWluIGluc2lnaHRzIGludG8gdGhlIGNvbGxhYm9yYXRpdmUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGRpZmZlcmVudCBpbnN0aXR1dGlvbnMgYW5kIGlkZW50aWZ5IGFueSBwYXR0ZXJucyBvciB0cmVuZHMgaW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiByZXNlYXJjaCBlZmZvcnRzLg0KDQpgYGB7cn0NCmZpZzVhIDwtIGJpYmxpb0FuYWx5c2lzKGJpYl9zY28pDQpwbG90KGZpZzVhKQ0KYGBgDQoNCiMjIGZpZzVjIC0gdGhlbWF0aWMgbWFwIGJhc2VkIG9uIGtleXdvcmRzDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMSksIG1hcj1jKDAsMiwwLDIpKQ0KZmlnNWMgPC0gdGhlbWF0aWNNYXAoYmliX3NjbywgZmllbGQgPSAiSUQiLCBuID0gMTAwMCwgbWluZnJlcSA9IDUsIHN0ZW1taW5nID0gRkFMU0UsIHNpemUgPSAwLjUsIG4ubGFiZWxzID0gMSwgcmVwZWwgPSBUUlVFKQ0KcGxvdChmaWc1YyRtYXApDQoNCmBgYA0KDQojIyBmaWcgNWQgLSBhdXRob3IgY29sbGFib3JhdGlvbiBuZXR3b3JrDQpgYGB7cn0NCk5ldE1hdHJpeF9hdXRob3JzIDwtIGJpYmxpb05ldHdvcmsoYmliX3NjbywgYW5hbHlzaXMgPSAiY29sbGFib3JhdGlvbiIsICBuZXR3b3JrID0gImF1dGhvcnMiLCBzZXAgPSAiOyIpDQpmaWc1ZCA8LSBuZXR3b3JrUGxvdChOZXRNYXRyaXhfYXV0aG9ycywgIG4gPSAxMDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaXRsZSA9ICJBdXRob3IgY29sbGFib3JhdGlvbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImF1dG8iLCBzaXplID0gNCwgc2l6ZS5jZXggPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRnZXNpemUgPSAxMCwgbGFiZWxzaXplID0gMS4xKQ0KYGBgDQoNCiMjIGZpZzVlIC0gY291bnRyeSBwdWJsaWNhdGlvbnMgbWFwDQpgYGB7cn0NCg0KYmlibWFwIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVMV9DTyIsIHNlcCA9ICI7IikgDQpiaWJtYXAgPC0gbWV0YVRhZ0V4dHJhY3Rpb24oYmlibWFwLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikgDQpmaXJzdGNvdW50cnljb3VudHMgPC0gYmlibWFwICU+JSANCiAgZ3JvdXBfYnkoQVUxX0NPKSAlPiUNCiAgY291bnQoKSAlPiUgDQogIGZpbHRlcighaXMubmEoQVUxX0NPKSkgIA0Kd29ybGRfbWFwIDwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSANCiAgZmlsdGVyKCEgbG9uZyA+IDE4MCkgDQpmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uIDwtIHN0cl90b190aXRsZShmaXJzdGNvdW50cnljb3VudHMkQVUxX0NPKQ0KZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbltmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uID09ICJVc2EiXSA8LSAiVVNBIiANCmZpcnN0Y291bnRyeWNvdW50cyRyZWdpb25bZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbiA9PSAiVW5pdGVkIEtpbmdkb20iXSA8LSAiVUsiIA0KZW1wdHltYXAgPC0gdGliYmxlKHJlZ2lvbiA9IHVuaXF1ZSh3b3JsZF9tYXAkcmVnaW9uKSwgbiA9IHJlcCgwLGxlbmd0aCh1bmlxdWUod29ybGRfbWFwJHJlZ2lvbikpKSkgDQpmdWxsbWFwIDwtIGxlZnRfam9pbihlbXB0eW1hcCwgZmlyc3Rjb3VudHJ5Y291bnRzLCBieSA9ICJyZWdpb24iKSANCmZ1bGxtYXAkbiA8LSBmdWxsbWFwJG4ueCArIGZ1bGxtYXAkbi55IA0KZnVsbG1hcCRuW2lzLm5hKGZ1bGxtYXAkbildIDwtIDAgDQoNCg0KDQpmaWc1ZSA8LSBmdWxsbWFwICU+JSANCiAgZ2dwbG90KGFlcyhmaWxsID0gbiwgbWFwX2lkID0gcmVnaW9uKSkgKw0KICBnZW9tX21hcChtYXAgPSB3b3JsZF9tYXAsIGNvbG9yID0gImdyYXk1MCIpICsNCiAgZXhwYW5kX2xpbWl0cyh4ID0gd29ybGRfbWFwJGxvbmcsIHkgPSB3b3JsZF9tYXAkbGF0KSArDQogIGNvb3JkX21hcCgibW9sbCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzk4RkI5OCIsIGhpZ2ggPSAiIzAwNjQwMCIsDQogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiU2NvcmUiLCBuYS52YWx1ZSA9ICJncmF5NzAiLA0KICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEsIDIwKSwNCiAgICAgIGd1aWRlID0gZ3VpZGVfY29sb3JiYXIoZGlyZWN0aW9uID0gInZlcnRpY2FsLiIpKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gdW5pdCgxMCwgdW5pdHMgPSAibW0iKSwgYmFyaGVpZ2h0ID0gdW5pdCgyMCwgdW5pdHMgPSAibW0iKSkpDQpmaWc1ZQ0KYGBgDQoNCiMjIE1hcCBvZiBldXJvcGUgDQpgYGB7cn0NCmZpZzVmIDwtIGZ1bGxtYXAgJT4lIA0KICBnZ3Bsb3QoYWVzKGZpbGwgPSBuLCBtYXBfaWQgPSByZWdpb24pKSArDQogIGdlb21fbWFwKG1hcCA9IHdvcmxkX21hcCwgY29sb3IgPSAiZ3JleTUwIikgKw0KICBjb29yZF9tYXAoIm1vbGwiLCB5bGltID0gYygzMCwgNzUpLCB4bGltID0gYygtMjUsIDQ1KSkgKyAjIHNldCBsaW1pdHMgZm9yIEV1cm9wZQ0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiM5OEZCOTgiLCBoaWdoID0gIiMwMDY0MDAiLA0KICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiU2NvcmUiLCBuYS52YWx1ZSA9ICJncmF5NzAiLA0KICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMSwgMTApLA0KICAgICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfY29sb3JiYXIoZGlyZWN0aW9uID0gInZlcnRpY2FsLiIpKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gdW5pdCgxMCwgdW5pdHMgPSAibW0iKSwgYmFyaGVpZ2h0ID0gdW5pdCgyMCwgdW5pdHMgPSAibW0iKSkpDQoNCmZpZzVmDQoNCg0KYGBgDQoNCiMjIGZpZzVmIC0gY291bnRyeSBjb2xsYWJvcmF0aW9uIG5ldHdvcmsgY2lyY2xlIHBsb3QNCmBgYHtyfQ0KIyBFeHRyYWN0IGNvdW50cmllcyBmcm9tIHRoZSBhZmZpbGlhdGlvbnMNCmJpYl9zY28yIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVX0NPIiwgc2VwID0gIjsiKQ0KDQojIENyZWF0ZSBhIG5ldHdvcmsgbWF0cml4IG9mIGNvbGxhYm9yYXRpb25zIGJldHdlZW4gY291bnRyaWVzDQpOZXRNYXRyaXhfY291bnRyeSA8LSBiaWJsaW9OZXR3b3JrKGJpYl9zY28yLCBhbmFseXNpcyA9ICJjb2xsYWJvcmF0aW9uIiwgbmV0d29yayA9ICJjb3VudHJpZXMiLCBzZXAgPSAiOyIpDQoNCiMgQ29udmVydCB0aGUgbmV0d29yayBtYXRyaXggdG8gYSBzdGFuZGFyZCBtYXRyaXgNCk5ldE1hdHJpeF9jb3VudHJ5IDwtIGFzLm1hdHJpeChOZXRNYXRyaXhfY291bnRyeSkNCg0KIyBSZW1vdmUgdGhlIGxvd2VyIHRyaWFuZ2xlIChhcyB0aGlzIGlzIGR1cGxpY2F0aW9uIG9mIGluZm8pDQpOZXRNYXRyaXhfY291bnRyeVtsb3dlci50cmkoTmV0TWF0cml4X2NvdW50cnkpXSA8LSAwIA0KDQojIENoYW5nZSBjb2x1bW4gYW5kIHJvdyBuYW1lcyB0byB0aXRsZSBjYXNlDQpjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPC0gc3RyX3RvX3RpdGxlKGNvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSkNCnJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA8LSBzdHJfdG9fdGl0bGUocm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpKQ0KDQojIENoYW5nZSAiVXNhIiB0byAiVVNBIg0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA9PSAiVXNhIl0gPC0gIlVTQSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVzYSJdIDwtICJVU0EiDQoNCiMgQ2hhbmdlICJVbml0ZWQgS2luZ2RvbSIgdG8gIlVLIiBmb3IgZWFzaWVyIHBsb3R0aW5nDQpjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSlbY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpID09ICJVbml0ZWQgS2luZ2RvbSJdIDwtICJVSyINCnJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVuaXRlZCBLaW5nZG9tIl0gPC0gIlVLIg0KDQojIERlZmluZSBjb2xvcnMgZm9yIGVhY2ggY291bnRyeQ0KbXkuY29sczIgPC0gYygNCiAgVVNBID0gIiMzNzdlYjgiLA0KICBTcGFpbiA9ICIjZmZmZjMzIiwNCiAgQ2hpbmEgPSAiI2U0MWExYyIsDQogIEZyYW5jZSA9ICIjOTk5OTk5IiwNCiAgQ2FuYWRhID0gIiNhNmNlZTMiLA0KICBEZW5tYXJrID0gIiNiMmRmOGEiLA0KICBOZXRoZXJsYW5kcyA9ICIjMzc3ZWI4IiwNCiAgQmVsZ2l1bSA9ICIjOTg0ZWEzIiwNCiAgVUsgPSAiI2ZmZmYzMyIsDQogIEF1c3RyYWxpYSA9ICIjNGRhZjRhIiwNCiAgQnJhemlsID0gIiM0ZGFmNGEiLA0KICBHZXJtYW55ID0gIiNiMmRmOGEiLA0KICBHcmVlY2UgPSAiI2Y3ODFiZiIsDQogIEtvcmVhID0gIiNmNzgxYmYiLA0KICBJcmVsYW5kID0gIiNhNjU2MjgiLA0KICBOb3J3YXkgPSAiI2ZmN2YwMCIsDQogIFN3ZWRlbiA9ICIjNGRhZjRhIiwNCiAgRWd5cHQgPSAiI2Y3ODFiZiIsDQogIEl0YWx5ID0gIiNlNDFhMWMiLA0KICBKYXBhbiA9ICIjMWY3OGI0IiwNCiAgU3dpdHplcmxhbmQgPSAiIzk4NGVhMyIsDQogIFR1cmtleSA9ICIjMzNhMDJjIiwNCiAgQXVzdHJpYSA9ICIjYjJkZjhhIiwNCiAgSXNyYWVsID0gIiNmNzgxYmYiLA0KICBOZXdaZWFsYW5kID0gIiM0ZGFmNGEiLA0KICBSdXNzaWEgPSAiIzk5OTk5OSIsDQogIFNpbmdhcG9yZSA9ICIjYjJkZjhhIiwNCiAgUG9ydHVnYWwgPSAiIzk4NGVhMyIsDQogIEZpbmxhbmQgPSAiI2IyZGY4YSIsDQogIE1leGljbyA9ICIjYTY1NjI4IiwNCiAgUG9sYW5kID0gIiNiMmRmOGEiLA0KICBTb3V0aEFmcmljYSA9ICIjZjc4MWJmIiwNCiAgQXJnZW50aW5hID0gIiNmZjdmMDAiLA0KICBDaGlsZSA9ICIjZmY3ZjAwIiwNCiAgQ3plY2hSZXB1YmxpYyA9ICIjYjJkZjhhIiwNCiAgSWNlbGFuZCA9ICIjYjJkZjhhIiwNCiAgUGVydSA9ICIjZmY3ZjAwIiwNCiAgUm9tYW5pYSA9ICIjZmI5YTk5IiwNCiAgU2VyYmlhID0gIiNmYjlhOTkiLA0KICBVQUUgPSAiI2E2NTYyOCINCikNCg0KDQojIENyZWF0ZSBhIGNob3JkIGRpYWdyYW0gb2YgdGhlIG5ldHdvcmsgbWF0cml4DQpmaWc1ZiA8LSBjaG9yZERpYWdyYW0oTmV0TWF0cml4X2NvdW50cnksIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxLCBncmlkLmNvbCA9IG15LmNvbHMyKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAuMSwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2subGVuZ3RoID0gMC41LCBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQoNCmBgYA0KDQojIyBmaWc1ZyBjb2xsYWJvcmF0aW9uIG1hdHJpeCB3aXRoIHNlbGYgY2l0YXRpb24gcmVtb3ZlZA0KYGBge3J9DQoNCmRpYWcoTmV0TWF0cml4X2NvdW50cnkpIDwtIDANCg0KIyBDcmVhdGUgYSBjaG9yZCBkaWFncmFtIG9mIHRoZSBuZXR3b3JrIG1hdHJpeA0KZmlnNWcgPC0gY2hvcmREaWFncmFtKE5ldE1hdHJpeF9jb3VudHJ5LCBhbm5vdGF0aW9uVHJhY2sgPSAiZ3JpZCIsIHByZUFsbG9jYXRlVHJhY2tzID0gMSwgZ3JpZC5jb2wgPSBteS5jb2xzMikNCg0KIyBBZGQgYSB0cmFjayB0byBsYWJlbCBlYWNoIHNlY3RvciB3aXRoIGl0cyBuYW1lDQpjaXJjb3MudHJhY2tQbG90UmVnaW9uKHRyYWNrLmluZGV4ID0gMSwgcGFuZWwuZnVuID0gZnVuY3Rpb24oeCwgeSkgew0KICB4bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ4bGltIikNCiAgeWxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieWxpbSIpDQogIHNlY3Rvci5uYW1lID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJzZWN0b3IuaW5kZXgiKQ0KICBjaXJjb3MudGV4dChtZWFuKHhsaW0pLCB5bGltWzFdICsgLjEsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMC41KSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0sIGJnLmJvcmRlciA9IE5BKQ0KYGBgDQoNCiMjIGZpZyA1aCBjb250aXRuZW50IGNvbGxhYm9yYXRpb24gDQpgYGB7cn0NCg0KDQpOZXRNYXRyaXhfY29udGluZW50IDwtIE5ldE1hdHJpeF9jb3VudHJ5DQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVVNBIl0gPC0gIk5vcnRoIEFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVVNBIl0gPC0gIk5vcnRoIEFtZXJpY2EiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTcGFpbiJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3BhaW4iXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2hpbmEiXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDaGluYSJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRnJhbmNlIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJGcmFuY2UiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2FuYWRhIl0gPC0gIk5vcnRoIEFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2FuYWRhIl0gPC0gIk5vcnRoIEFtZXJpY2EiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJEZW5tYXJrIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJEZW5tYXJrIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk5ldGhlcmxhbmRzIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOZXRoZXJsYW5kcyJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJCZWxnaXVtIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJCZWxnaXVtIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVLIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJVSyJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiQXVzdHJhbGlhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkF1c3RyYWxpYSJdIDwtICJBdXN0cmFsaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJCcmF6aWwiXSA8LSAiU291dGggQW1lcmljYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJCcmF6aWwiXSA8LSAiU291dGggQW1lcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkdlcm1hbnkiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkdlcm1hbnkiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRmlubGFuZCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRmlubGFuZCJdIDwtICJFdXJvcGUiDQoNCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkdyZWVjZSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiR3JlZWNlIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIktvcmVhIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiS29yZWEiXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk5vcndheSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTm9yd2F5Il0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlN3ZWRlbiJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dlZGVuIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkVneXB0Il0gPC0gIkFmcmljYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJFZ3lwdCJdIDwtICJBZnJpY2EiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJdGFseSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXRhbHkiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSmFwYW4iXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJKYXBhbiJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUG9ydHVnYWwiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlBvcnR1Z2FsIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlN3aXR6ZXJsYW5kIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTd2l0emVybGFuZCJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJUdXJrZXkiXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJUdXJrZXkiXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkluZGlhIl0gPC0gIkFzaWEiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSW5kaWEiXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIklyYW4iXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJcmFuIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDb3N0YSBSaWNhIl0gPC0gIk5vcnRoIEFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ29zdGEgUmljYSJdIDwtICJOb3J0aCBBbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ3plY2ggUmVwdWJsaWMiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkN6ZWNoIFJlcHVibGljIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkhvbmcgS29uZyJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkhvbmcgS29uZyJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSWNlbGFuZCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSWNlbGFuZCJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJcmVsYW5kIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJcmVsYW5kIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk1leGljbyJdIDwtICJOb3J0aCBBbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIk1leGljbyJdIDwtICJOb3J0aCBBbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUm9tYW5pYSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUm9tYW5pYSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTbG92YWtpYSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU2xvdmFraWEiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVWtyYWluZSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVWtyYWluZSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiT2NlYW5pYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiT2NlYW5pYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkthemFraHN0YW4iXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLYXpha2hzdGFuIl0gPC0gIkFzaWEiDQoNCg0KIyBjb2xsYXBzaW5nDQptZXJnZV9tYXRyaXggPC0gdChyb3dzdW0odChOZXRNYXRyaXhfY29udGluZW50KSwgZ3JvdXAgPSBjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSwgbmEucm0gPSBUKSkNCm1lcmdlX21hdHJpeDIgPC0gcm93c3VtKG1lcmdlX21hdHJpeCwgZ3JvdXAgPSByb3duYW1lcyhtZXJnZV9tYXRyaXgpKQ0KIyByZW1vdmUgZGlhZ29uYWwgZWxlbWVudHMNCmRpYWcobWVyZ2VfbWF0cml4MikgPC0gMA0KIyBjaG9yZCBwbG90DQpjaG9yZERpYWdyYW1Gcm9tTWF0cml4KG1lcmdlX21hdHJpeDIpDQoNCiMgRGVmaW5lIGNvbG9ycyBmb3IgZWFjaCBjb250aW5lbnQNCm15LmNvbHMyIDwtIGMoDQogIEFmcmljYSA9ICIjQ0M3OUE3IiwNCiAgTm9ydGhBbWVyaWNhID0gIiNGMEU0NDIiLA0KICBBc2lhID0gIiMwMDcyQjIiLA0KICBFdXJvcGUgPSAiI0U2OUYwMCIsDQogIE9jZWFuaWEgPSAiIzAwOUU3MyIsDQogIFNvdXRoQW1lcmljYSA9ICIjRDU1RTAwIg0KKQ0KDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZzVoIDwtIGNob3JkRGlhZ3JhbShtZXJnZV9tYXRyaXgyLCBhbm5vdGF0aW9uVHJhY2sgPSAiZ3JpZCIsIHByZUFsbG9jYXRlVHJhY2tzID0gMSkNCiMgQWRkIGEgdHJhY2sgdG8gbGFiZWwgZWFjaCBzZWN0b3Igd2l0aCBpdHMgbmFtZQ0KY2lyY29zLnRyYWNrUGxvdFJlZ2lvbih0cmFjay5pbmRleCA9IDEsIHBhbmVsLmZ1biA9IGZ1bmN0aW9uKHgsIHkpIHsNCiAgeGxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieGxpbSIpDQogIHlsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInlsaW0iKQ0KICBzZWN0b3IubmFtZSA9IGdldC5jZWxsLm1ldGEuZGF0YSgic2VjdG9yLmluZGV4IikNCiAgY2lyY29zLnRleHQobWVhbih4bGltKSwgeWxpbVsxXSArIDAuMiwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2subGVuZ3RoID0gMC4yLCBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQoNCmBgYA0KDQoNCg0KYGBge3IgbW9zdCBjaXRlZCBhcnRpY2xlcyBhbmQgYXV0aG9yc30NCg0KQ1IgPC0gY2l0YXRpb25zKGJpYl9zY28sIGZpZWxkID0gImFydGljbGUiLCBzZXAgPSAiOyIpICNsaXN0IG9mIG1vc3QgY2l0ZWQgYXJ0aWNsZXMNCiBjYmluZChDUiRDaXRlZFsxOjEwXSkgI3RlbiBtb3N0IGNpdGVkIGFydGljbGVzDQogDQpDUiA8LSBjaXRhdGlvbnMoYmliX3NjbywgZmllbGQgPSAiYXV0aG9yIiwgc2VwID0gIjsiKQ0KY2JpbmQoQ1IkQ2l0ZWRbMToxMF0pICN0ZW4gbW9zdCBjaXRlZCBhdXRob3JzDQpgYGAgDQoNCmBgYHtyIGJpYmxpb21ldHJpYyBjb3VwbGluZyBuZXR3b3JrfQ0KTmV0TWF0cml4X2NvdXBsaW5nIDwtIGJpYmxpb05ldHdvcmsoYmliX3NjbywgYW5hbHlzaXMgPSAiY291cGxpbmciLCBuZXR3b3JrID0gInJlZmVyZW5jZXMiLCBzZXAgPSAiOyAiKQ0KTmV0TWF0cml4X2NvdXBsaW5nX3Bsb3QgPC0gbmV0d29ya1Bsb3QoTmV0TWF0cml4X2NvdXBsaW5nLCBuID0gMjAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGl0bGUgPSAiUGFwZXIgY28tY2l0YXRpb24iLCB0eXBlID0gImZydWNodGVybWFuIiwgc2l6ZT1ULCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZS5tdWx0aXBsZT1GQUxTRSwgbGFiZWxzaXplPTAuOCxlZGdlc2l6ZSA9IDUpDQpgYGANCg0KDQo=